81 Commits

Author SHA1 Message Date
9a22bf965d _handle track fix
Some checks failed
Build Android / Game (Android, Release ARM64) (push) Has been cancelled
Build iOS / Game (iOS, Release ARM64) (push) Has been cancelled
Build Linux / Editor (Linux, Development x64) (push) Has been cancelled
Build Linux / Game (Linux, Release x64) (push) Has been cancelled
Build macOS / Editor (Mac, Development ARM64) (push) Has been cancelled
Build macOS / Game (Mac, Release ARM64) (push) Has been cancelled
Build Windows / Editor (Windows, Development x64) (push) Has been cancelled
Build Windows / Game (Windows, Release x64) (push) Has been cancelled
Cooker / Cook (Mac) (push) Has been cancelled
Tests / Tests (Linux) (push) Has been cancelled
Tests / Tests (Windows) (push) Has been cancelled
2025-12-16 00:15:40 +02:00
88f8bb1e29 _wip 2025-12-16 00:15:40 +02:00
8efc4715c6 Improve Linux .NET runtime identifier detection
Use the runtime identifier detected during runtime instead of
calling the dotnet tool in order to query it.
2025-12-16 00:15:40 +02:00
48c60144ae Set C# language version to 14 with .NET 10 2025-12-16 00:15:40 +02:00
249cde467e Improve installed .NET runtime version detection 2025-12-16 00:15:40 +02:00
e2eadc87b6 Fix Editor state after loading a scene without compiled game modules 2025-12-16 00:15:40 +02:00
bc4b94d2bc Use in over ref modifier in Math functions input parameters 2025-12-16 00:15:30 +02:00
ecf074801f Fix ref usage warnings with in-parameters 2025-12-16 00:15:30 +02:00
74bac97f44 Deprecate UseFastPDBLinking
This is no longer supported in VS2026
2025-12-16 00:15:30 +02:00
d7eebb699c Pass const ref parameters as in parameters in C# bindings
_amend in parameters
2025-12-16 00:15:29 +02:00
dde07bac8d Fix mixed newline characters in generated bindings 2025-12-16 00:14:16 +02:00
5c8e593d89 Show properties without getter in generic editor 2025-12-16 00:14:16 +02:00
46fd5a5855 Ensure Flax.Build tasks and utilities output error messages as errors 2025-12-16 00:11:06 +02:00
74c1e200ce Implement Platform::CreateProcess with SDL backend
Supports handling process standard output and standard error
streams separately in realtime.
2025-12-16 00:10:01 +02:00
31945a53a2 Update SDL to 3.3.4 2025-12-15 19:32:47 +02:00
3e91ba3fb2 Merge remote-tracking branch 'origin/master' into sdl_platform 2025-12-15 19:03:05 +02:00
Wojtek Figat
e257f9e4a0 Merge branch 'Tryibion-fix-anim-slot-replay' 2025-12-14 23:03:45 +01:00
Wojtek Figat
056de752ed Add docs 2025-12-14 23:03:34 +01:00
Wojtek Figat
76700c0b24 Merge branch 'fix-anim-slot-replay' of https://github.com/Tryibion/FlaxEngine into Tryibion-fix-anim-slot-replay 2025-12-14 23:01:21 +01:00
Wojtek Figat
9fdcff657d Merge branch 'VitaminCpp-late_join_fix' 2025-12-14 22:58:55 +01:00
Wojtek Figat
2b6339c05c Minor code cleanup 2025-12-14 22:58:53 +01:00
Wojtek Figat
bb91202439 Merge branch 'late_join_fix' of https://github.com/VitaminCpp/FlaxEngine into VitaminCpp-late_join_fix 2025-12-14 22:49:49 +01:00
Wojtek Figat
f25e9f262a Merge branch 'VitaminCpp-replication_hashing_fix' 2025-12-14 22:48:09 +01:00
Wojtek Figat
ee51077f49 Merge branch 'replication_hashing_fix' of https://github.com/VitaminCpp/FlaxEngine into VitaminCpp-replication_hashing_fix 2025-12-14 22:43:58 +01:00
Wojtek Figat
950e958a58 Merge branch 'VitaminCpp-hash_set_crash_fix' 2025-12-14 22:41:11 +01:00
Wojtek Figat
5fdbed2b56 Minor codestyle adjustments 2025-12-14 22:41:00 +01:00
Chandler Cox
0e627577fc Simplify code. 2025-12-14 15:00:44 -06:00
Wojtek Figat
4846d4b024 Merge branch 'hash_set_crash_fix' of https://github.com/VitaminCpp/FlaxEngine into VitaminCpp-hash_set_crash_fix 2025-12-14 21:52:40 +01:00
Wojtek Figat
5e5293bf7b Merge branch 'GoaLitiuM-oob_write_fix' 2025-12-14 21:31:42 +01:00
Wojtek Figat
d88477dcae Merge branch 'oob_write_fix' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-oob_write_fix 2025-12-14 21:31:37 +01:00
Wojtek Figat
bd58bd91b4 Merge branch 'ThePhantomMask-AddDropdownHighlightedColor' 2025-12-13 23:14:47 +01:00
Wojtek Figat
7ce0d88bdc Merge branch 'AddDropdownHighlightedColor' of https://github.com/ThePhantomMask/FlaxEngine into ThePhantomMask-AddDropdownHighlightedColor 2025-12-13 23:14:09 +01:00
Wojtek Figat
98bb2d40d6 Merge branch 'Inertia-Squared-hyprland-fix' 2025-12-13 23:13:30 +01:00
Wojtek Figat
f4bc620bbd Merge branch 'hyprland-fix' of https://github.com/Inertia-Squared/FlaxEngine into Inertia-Squared-hyprland-fix 2025-12-13 23:13:26 +01:00
Wojtek Figat
0313bf32c9 Merge branch 'AcidicVoid-master' 2025-12-13 23:11:05 +01:00
Wojtek Figat
0c887cd29e Use fix from #3830 in particle and anim graphs too 2025-12-13 23:11:01 +01:00
Wojtek Figat
5bd9bce634 Merge branch 'master' of https://github.com/AcidicVoid/FlaxEngine into AcidicVoid-master 2025-12-13 23:08:01 +01:00
Wojtek Figat
2a53d0a462 Fix crash on Visual Script missing asset ref after hot-reload in Editor
#3823
2025-12-13 02:10:41 +01:00
82bd915274 Fix out-of-bounds write while parsing command-line arguments 2025-12-12 14:47:15 +02:00
Wojtek Figat
71391cf1cc Fix deprecated tag placement 2025-12-11 16:38:28 +01:00
Wojtek Figat
b5286af526 Attempt to fix regression from 32bd72fecd 2025-12-11 14:48:18 +01:00
Wojtek Figat
9f07a2a54e Attempt to fix regression from 32bd72fecd 2025-12-10 18:58:43 +01:00
Wojtek Figat
c39c642b60 Add safety check for invalid math values in shader graph generation 2025-12-10 17:39:18 +01:00
Wojtek Figat
02cff3973a Bump up engine version 2025-12-10 15:01:53 +01:00
Wojtek Figat
a63b97d31d Add stripping DXIL debug data from the shader cache when not used 2025-12-10 14:58:12 +01:00
Wojtek Figat
ca52122656 Fix validation error on Windows for textures but optimize buffers instead 2025-12-10 14:53:51 +01:00
Wojtek Figat
20a7fcf6a0 Add profiler wait event for GPU wait on D3D12 2025-12-10 13:01:24 +01:00
Wojtek Figat
43665aa7eb Rename GPUContext::ClearState to ResetState for constentency 2025-12-10 13:00:59 +01:00
Wojtek Figat
3b9b49950c Fixes for Xbox One 2025-12-10 09:48:47 +01:00
Wojtek Figat
0a8752ec0a Fix cross-building building engine with separate executable and library for Unix platforms on Windows 2025-12-10 09:48:27 +01:00
Wojtek Figat
47685dc2be Merge branch 'VitaminCpp-missing_move_semantics_fix' 2025-12-09 10:00:55 +01:00
Wojtek Figat
517ee5bb25 Merge branch 'missing_move_semantics_fix' of https://github.com/VitaminCpp/FlaxEngine into VitaminCpp-missing_move_semantics_fix 2025-12-09 10:00:51 +01:00
Wojtek Figat
3ab01d3576 Merge branch 'VitaminCpp-minor_mem_layout_opt' 2025-12-09 10:00:20 +01:00
Wojtek Figat
31b6d4d658 Merge branch 'minor_mem_layout_opt' of https://github.com/VitaminCpp/FlaxEngine into VitaminCpp-minor_mem_layout_opt 2025-12-09 10:00:16 +01:00
Wojtek Figat
08f840d642 Merge branch 'Tryibion-fix-exception-reload' 2025-12-09 09:59:56 +01:00
Wojtek Figat
776b6259cd Merge branch 'fix-exception-reload' of https://github.com/Tryibion/FlaxEngine into Tryibion-fix-exception-reload 2025-12-09 09:59:34 +01:00
Wojtek Figat
5c81c71116 Move constant buffer init for instanced draws only, others do it in all paths 2025-12-09 09:51:53 +01:00
Wojtek Figat
188b635ea0 Merge remote-tracking branch 'origin/master' 2025-12-09 09:48:05 +01:00
Wojtek Figat
56066a3212 Porting to a famous blue platform 2025-12-08 14:41:55 -08:00
Phantom
ed50ce9c90 Change Dropdown's EditorOrder from 2023 to 2024 2025-12-07 18:48:16 +01:00
Phantom
a7e77f6e21 Update CreatePopupItem method
-Modify the `TextColour` property to use a dynamic value based on `TextColour` multiplied by `0.9f` instead of a fixed value (`Colour.White * 0.9f`).
-Modify the `TextColourHighlighted` property to use the dynamic value of `TextColourHighlighted` instead of a fixed value (`Colour.White`).
2025-12-07 18:23:38 +01:00
Phantom
56278b17ee Add Text Color Highlighted on Dropdown 2025-12-07 16:53:43 +01:00
Wojtek Figat
bd78db72b9 Add Mono AOT dynamic module preloading to speed up startup time 2025-12-05 03:46:28 -08:00
Wojtek Figat
32bd72fecd Minor fix to the game cooker assets summary log of a single asset 2025-12-04 23:51:07 +01:00
Wojtek Figat
3a798a70fa Fix collections capacity growing to use the closest power of two
Capacity was incorrectly 2x larger than needed.
Added unit test to ensure it stays correct.
2025-12-04 23:29:15 +01:00
Wojtek Figat
02429266b1 Fix Array::RemoveAtKeepOrder to avoid memory override with large mem copy 2025-12-03 05:03:21 -08:00
Wojtek Figat
77aea0c69c Fix fatal error reporting from multiple therads to sync and properly log (eg. out of memory) 2025-12-01 08:18:54 -08:00
Inertia
6a3ce862cb - Add X11 Class hints for easy hooking by WMs for window-specific rules (required to fix some bugs in WMs like Hyprland) 2025-12-01 11:19:35 +11:00
Wojtek Figat
93217da619 Add option to merge vertex layout with reference order maintained 2025-11-29 15:04:11 -08:00
VitaminCpp
63def54dad Merge branch 'FlaxEngine:master' into hash_set_crash_fix 2025-11-28 15:55:15 +01:00
Michael Herzog
00f9a28729 Fixed HashSet compaction count after mid-compact growth
Ensure HashSetBase::Compact() preserves _elementsCount even when EnsureCapacity() triggers during compaction. The growth path resets the counter; we now cache the original count and restore it after moving all buckets so Count() stays correct in heavy-collision scenarios.
2025-11-28 15:51:57 +01:00
Michael Herzog
56beca0db4 Fixed network replicated-object deduplication by hashing/equality on ObjectId
Aligned NetworkReplicatedObject equality with its hash (compare ObjectId, not pointer).
2025-11-27 23:28:17 +01:00
Alex Ray
64cd898a65 Bypassing Call Logic in Editor Preview 2025-11-27 18:09:11 +01:00
VitaminCpp
90472a4b31 Merge branch 'FlaxEngine:master' into late_join_fix 2025-11-27 10:33:53 +01:00
Michael Herzog
0007185b5f Fixed late-join network replication
- Adjusted replication to resend unchanged state only to missing clients.
- Skip server serialization when no recipients, and downgrade unknown-despawn noise.
2025-11-26 17:54:49 +01:00
Chandler Cox
1bf6612002 Fix exception thrown when reloading open windows. 2025-11-25 17:26:57 -06:00
Michael Herzog
d9a18b1d31 Fixed HashSet compact rehash under heavy collisions
- Compact now iterates over the old bucket array using the saved oldSize, and frees with that size, avoiding out-of-bounds when _size changes.
- If reinsertion finds no free slot during compaction (pathological collisions), the table grows once and retries, preventing AVs.
- This fix addresses problems with weak hash keys (like #3824).
2025-11-25 21:23:49 +01:00
Michael Herzog
465f30661f Minor memory layout optimization 2025-11-25 17:36:49 +01:00
Michael Herzog
a62ca5452e Fixed missing move semantics in script object reference 2025-11-25 17:33:11 +01:00
Chandler Cox
2d56411e5f Add slot stop methods without anim param. 2025-11-23 14:19:37 -06:00
Chandler Cox
f8dc8ab903 Fix not being able to replay same animation in animation slot. 2025-11-23 14:19:11 -06:00
121 changed files with 3936 additions and 597 deletions

View File

@@ -4,7 +4,7 @@
"Major": 1,
"Minor": 11,
"Revision": 0,
"Build": 6804
"Build": 6805
},
"Company": "Flax",
"Copyright": "Copyright (c) 2012-2025 Wojciech Figat. All rights reserved.",

View File

@@ -281,6 +281,13 @@ namespace FlaxEditor.Content
private void CacheData()
{
if (!_asset)
{
_parameters = Utils.GetEmptyArray<ScriptMemberInfo>();
_methods = Utils.GetEmptyArray<ScriptMemberInfo>();
_attributes = Utils.GetEmptyArray<Attribute>();
return;
}
if (_parameters != null)
return;
if (_asset.WaitForLoaded())
@@ -344,13 +351,13 @@ namespace FlaxEditor.Content
}
/// <inheritdoc />
public string Name => Path.GetFileNameWithoutExtension(_asset.Path);
public string Name => _asset ? Path.GetFileNameWithoutExtension(_asset.Path) : null;
/// <inheritdoc />
public string Namespace => string.Empty;
/// <inheritdoc />
public string TypeName => JsonSerializer.GetStringID(_asset.ID);
public string TypeName => _asset ? JsonSerializer.GetStringID(_asset.ID) : null;
/// <inheritdoc />
public bool IsPublic => true;

View File

@@ -1368,7 +1368,10 @@ bool CookAssetsStep::Perform(CookingData& data)
{
typeName = e.TypeName;
}
LOG(Info, "{0}: {1:>4} assets of total size {2}", typeName, e.Count, Utilities::BytesToText(e.ContentSize));
if (e.Count == 1)
LOG(Info, "{0}: 1 asset of total size {1}", typeName, Utilities::BytesToText(e.ContentSize));
else
LOG(Info, "{0}: {1:>4} assets of total size {2}", typeName, e.Count, Utilities::BytesToText(e.ContentSize));
}
LOG(Info, "");
}

View File

@@ -897,9 +897,11 @@ namespace FlaxEditor.Modules
if (type.IsAssignableTo(typeof(AssetEditorWindow)))
{
var ctor = type.GetConstructor(new Type[] { typeof(Editor), typeof(AssetItem) });
var assetItem = Editor.ContentDatabase.FindAsset(winData.AssetItemID);
var assetType = assetItem.GetType();
var ctor = type.GetConstructor(new Type[] { typeof(Editor), assetType });
var win = (AssetEditorWindow)ctor.Invoke(new object[] { Editor.Instance, assetItem });
win.Show(winData.DockState, winData.DockState != DockState.Float ? winData.DockedTo : null, winData.SelectOnShow, winData.SplitterValue);
if (winData.DockState == DockState.Float)
{

View File

@@ -406,6 +406,8 @@ namespace FlaxEngine.Utilities
{
if (type == ScriptType.Null)
return null;
if (type.BaseType == null)
return type.Type;
while (type.Type == null)
type = type.BaseType;
return type.Type;

View File

@@ -400,7 +400,7 @@ namespace FlaxEditor.Surface
return scriptType.GetGenericTypeDefinition() == typeof(Dictionary<,>);
}
var managedType = TypeUtils.GetType(scriptType);
return !TypeUtils.IsDelegate(managedType);
return managedType != null && !TypeUtils.IsDelegate(managedType);
}
internal static bool IsValidVisualScriptFunctionType(ScriptType scriptType)
@@ -408,7 +408,7 @@ namespace FlaxEditor.Surface
if (scriptType.IsGenericType || scriptType.IsStatic || !scriptType.IsPublic || scriptType.HasAttribute(typeof(HideInEditorAttribute), true))
return false;
var managedType = TypeUtils.GetType(scriptType);
return !TypeUtils.IsDelegate(managedType);
return managedType != null && !TypeUtils.IsDelegate(managedType);
}
internal static string GetVisualScriptTypeDescription(ScriptType type)

View File

@@ -2441,10 +2441,14 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu
{
if (bucket.LoopsLeft == 0)
{
// End playing animation
// End playing animation and reset bucket params
value = tryGetValue(node->GetBox(1), Value::Null);
bucket.Index = -1;
slot.Animation = nullptr;
bucket.TimePosition = 0.0f;
bucket.BlendInPosition = 0.0f;
bucket.BlendOutPosition = 0.0f;
bucket.LoopsDone = 0;
return;
}
@@ -2553,9 +2557,15 @@ void AnimGraphExecutor::ProcessGroupFunction(Box* boxBase, Node* node, Value& va
// Function Input
case 1:
{
// Skip when graph is too small (eg. preview) and fallback with default value from the function graph
if (context.GraphStack.Count() < 2)
{
value = tryGetValue(node->TryGetBox(1), Value::Zero);
break;
}
// Find the function call
AnimGraphNode* functionCallNode = nullptr;
ASSERT(context.GraphStack.Count() >= 2);
Graph* graph;
for (int32 i = context.CallStack.Count() - 1; i >= 0; i--)
{

View File

@@ -658,7 +658,10 @@ public:
--_count;
T* data = _allocation.Get();
if (index < _count)
Memory::MoveAssignItems(data + index, data + (index + 1), _count - index);
{
for (int32 i = index; i < _count; i++)
data[i] = MoveTemp(data[i + 1]);
}
Memory::DestructItems(data + _count, 1);
}

View File

@@ -409,27 +409,36 @@ protected:
else
{
// Rebuild entire table completely
const int32 elementsCount = _elementsCount;
const int32 oldSize = _size;
AllocationData oldAllocation;
AllocationUtils::MoveToEmpty<BucketType, AllocationType>(oldAllocation, _allocation, _size, _size);
AllocationUtils::MoveToEmpty<BucketType, AllocationType>(oldAllocation, _allocation, oldSize, oldSize);
_allocation.Allocate(_size);
BucketType* data = _allocation.Get();
for (int32 i = 0; i < _size; ++i)
for (int32 i = 0; i < oldSize; ++i)
data[i]._state = HashSetBucketState::Empty;
BucketType* oldData = oldAllocation.Get();
FindPositionResult pos;
for (int32 i = 0; i < _size; ++i)
for (int32 i = 0; i < oldSize; ++i)
{
BucketType& oldBucket = oldData[i];
if (oldBucket.IsOccupied())
{
FindPosition(oldBucket.GetKey(), pos);
ASSERT(pos.FreeSlotIndex != -1);
if (pos.FreeSlotIndex == -1)
{
// Grow and retry to handle pathological cases (eg. heavy collisions)
EnsureCapacity(_size + 1, true);
FindPosition(oldBucket.GetKey(), pos);
ASSERT(pos.FreeSlotIndex != -1);
}
BucketType& bucket = _allocation.Get()[pos.FreeSlotIndex];
bucket = MoveTemp(oldBucket);
}
}
for (int32 i = 0; i < _size; ++i)
for (int32 i = 0; i < oldSize; ++i)
oldData[i].Free();
_elementsCount = elementsCount;
}
_deletedCount = 0;
}

View File

@@ -18,9 +18,7 @@ namespace AllocationUtils
capacity |= capacity >> 8;
capacity |= capacity >> 16;
uint64 capacity64 = (uint64)(capacity + 1) * 2;
if (capacity64 > MAX_int32)
capacity64 = MAX_int32;
return (int32)capacity64;
return capacity64 >= MAX_int32 ? MAX_int32 : (int32)capacity64 / 2;
}
// Aligns the input value to the next power of 2 to be used as bigger memory allocation block.

View File

@@ -364,8 +364,8 @@ namespace FlaxEngine.Interop
private GCHandle handle;
private static HashSet<IntPtr> _weakHandles = new HashSet<nint>();
private static Dictionary<IntPtr, string> _handles = new();
private static Dictionary<IntPtr, string> _handles2 = new();
private static ConcurrentDictionary<IntPtr, string> _handles = new();
private static ConcurrentDictionary<IntPtr, string> _handles2 = new();
private ManagedHandle(IntPtr handle) => this.handle = GCHandle.FromIntPtr(handle);
@@ -379,14 +379,14 @@ namespace FlaxEngine.Interop
if (type == GCHandleType.Weak || type == GCHandleType.WeakTrackResurrection)
_weakHandles.Add((IntPtr)handle);
else if (_handles.Count < 14000)
_handles.Add((IntPtr)handle, value?.GetType().FullName ?? "");
_handles.TryAdd((IntPtr)handle, value?.GetType().FullName ?? "");
else
{
if (_handles2.Count > 12)
type = type;
if (value?.GetType() == typeof(string))
type = type;
_handles2.Add((IntPtr)handle, value?.GetType().FullName ?? "");
_handles2.TryAdd((IntPtr)handle, value?.GetType().FullName ?? "");
}
}
#else
@@ -414,11 +414,11 @@ namespace FlaxEngine.Interop
handle = handle;
handle = handle;
}
else if (_handles.Remove((IntPtr)handle))
else if (_handles.Remove((IntPtr)handle, out _))
{
handle = handle;
}
else if (_handles2.Remove((IntPtr)handle))
else if (_handles2.Remove((IntPtr)handle, out _))
{
handle = handle;
}

View File

@@ -67,7 +67,7 @@ void GPUContext::FrameBegin()
void GPUContext::FrameEnd()
{
ClearState();
ResetState();
FlushState();
}

View File

@@ -189,7 +189,7 @@ public:
/// [Deprecated in v1.10]
/// </summary>
/// <returns><c>true</c> if depth buffer is binded; otherwise, <c>false</c>.</returns>
DEPRECATED("IsDepthBufferBinded has been deprecated and will be removed in ")
DEPRECATED("IsDepthBufferBinded has been deprecated and will be removed in future")
virtual bool IsDepthBufferBinded() = 0;
public:
@@ -617,8 +617,17 @@ public:
/// <summary>
/// Clears the context state.
/// [Deprecated in v1.12]
/// </summary>
API_FUNCTION() virtual void ClearState() = 0;
API_FUNCTION() DEPRECATED("Use ResetState instead") void ClearState()
{
ResetState();
}
/// <summary>
/// Resets the context state.
/// </summary>
API_FUNCTION() virtual void ResetState() = 0;
/// <summary>
/// Flushes the internal cached context state with a command buffer.

View File

@@ -201,6 +201,7 @@ bool DeferredMaterialShader::Load()
psDesc.DepthWriteEnable = true;
psDesc.DepthEnable = true;
psDesc.DepthFunc = ComparisonFunc::Less;
psDesc.BlendMode.RenderTargetWriteMask = BlendingMode::ColorWrite::None;
psDesc.HS = nullptr;
psDesc.DS = nullptr;
GPUShaderProgramVS* instancedDepthPassVS;

View File

@@ -195,5 +195,10 @@ bool ForwardMaterialShader::Load()
psDesc.VS = _shader->GetVS("VS_Skinned");
_cache.DepthSkinned.Init(psDesc);
#if PLATFORM_PS5
// Fix shader binding issues on forward shading materials on PS5
_drawModes = DrawPass::None;
#endif
return false;
}

View File

@@ -264,5 +264,10 @@ bool ParticleMaterialShader::Load()
// Lazy initialization
_cacheVolumetricFog.Desc.PS = nullptr;
#if PLATFORM_PS5
// Fix shader binding issues on forward shading materials on PS5
_drawModes = DrawPass::None;
#endif
return false;
}

View File

@@ -113,7 +113,8 @@ GPUTexture* RenderBuffers::RequestHalfResDepth(GPUContext* context)
PixelFormat RenderBuffers::GetOutputFormat() const
{
return _useAlpha ? PixelFormat::R16G16B16A16_Float : PixelFormat::R11G11B10_Float;
// TODO: fix incorrect alpha leaking into reflections on PS5 with R11G11B10_Float
return _useAlpha || PLATFORM_PS5 ? PixelFormat::R16G16B16A16_Float : PixelFormat::R11G11B10_Float;
}
bool RenderBuffers::GetUseAlpha() const

View File

@@ -216,20 +216,21 @@ GPUVertexLayout* GPUVertexLayout::Get(const Span<GPUVertexLayout*>& layouts)
return result;
}
GPUVertexLayout* GPUVertexLayout::Merge(GPUVertexLayout* base, GPUVertexLayout* reference, bool removeUnused, bool addMissing, int32 missingSlotOverride)
GPUVertexLayout* GPUVertexLayout::Merge(GPUVertexLayout* base, GPUVertexLayout* reference, bool removeUnused, bool addMissing, int32 missingSlotOverride, bool referenceOrder)
{
GPUVertexLayout* result = base ? base : reference;
if (base && reference && base != reference)
{
bool elementsModified = false;
Elements newElements = base->GetElements();
const Elements& refElements = reference->GetElements();
if (removeUnused)
{
for (int32 i = newElements.Count() - 1; i >= 0; i--)
{
bool missing = true;
const VertexElement& e = newElements.Get()[i];
for (const VertexElement& ee : reference->GetElements())
for (const VertexElement& ee : refElements)
{
if (ee.Type == e.Type)
{
@@ -247,7 +248,7 @@ GPUVertexLayout* GPUVertexLayout::Merge(GPUVertexLayout* base, GPUVertexLayout*
}
if (addMissing)
{
for (const VertexElement& e : reference->GetElements())
for (const VertexElement& e : refElements)
{
bool missing = true;
for (const VertexElement& ee : base->GetElements())
@@ -282,6 +283,32 @@ GPUVertexLayout* GPUVertexLayout::Merge(GPUVertexLayout* base, GPUVertexLayout*
}
}
}
if (referenceOrder)
{
for (int32 i = 0, j = 0; i < newElements.Count() && j < refElements.Count(); j++)
{
if (newElements[i].Type == refElements[j].Type)
{
// Elements match so move forward
i++;
continue;
}
// Find reference element in a new list
for (int32 k = i + 1; k < newElements.Count(); k++)
{
if (newElements[k].Type == refElements[j].Type)
{
// Move matching element to the reference position
VertexElement e = newElements[k];
newElements.RemoveAt(k);
newElements.Insert(i, e);
i++;
break;
}
}
}
}
if (elementsModified)
result = Get(newElements, true);
}

View File

@@ -84,8 +84,9 @@ public:
/// <param name="removeUnused">True to remove elements from base layout that don't exist in a reference layout.</param>
/// <param name="addMissing">True to add missing elements to base layout that exist in a reference layout.</param>
/// <param name="missingSlotOverride">Allows to override the input slot for missing elements. Use value -1 to inherit slot from the reference layout.</param>
/// <param name="referenceOrder">True to reorder result elements to match the reference layout. For example, if input vertex buffer layout is different than vertex shader then it can match those.</param>
/// <returns>Vertex layout object. Doesn't need to be cleared as it's cached for an application lifetime.</returns>
static GPUVertexLayout* Merge(GPUVertexLayout* base, GPUVertexLayout* reference, bool removeUnused = false, bool addMissing = true, int32 missingSlotOverride = -1);
static GPUVertexLayout* Merge(GPUVertexLayout* base, GPUVertexLayout* reference, bool removeUnused = false, bool addMissing = true, int32 missingSlotOverride = -1, bool referenceOrder = false);
public:
// [GPUResource]

View File

@@ -724,7 +724,7 @@ void GPUContextDX11::SetState(GPUPipelineState* state)
}
}
void GPUContextDX11::ClearState()
void GPUContextDX11::ResetState()
{
if (!_context)
return;

View File

@@ -158,7 +158,7 @@ public:
void SetScissor(const Rectangle& scissorRect) override;
GPUPipelineState* GetState() const override;
void SetState(GPUPipelineState* state) override;
void ClearState() override;
void ResetState() override;
void FlushState() override;
void Flush() override;
void UpdateBuffer(GPUBuffer* buffer, const void* data, uint32 size, uint32 offset) override;

View File

@@ -143,6 +143,8 @@ void CommandQueueDX12::WaitForFence(uint64 fenceValue)
void CommandQueueDX12::WaitForGPU()
{
PROFILE_CPU();
ZoneColor(TracyWaitZoneColor);
const uint64 value = _fence.Signal(this);
_fence.WaitCPU(value);
}

View File

@@ -137,7 +137,7 @@ bool GPUBufferDX12::OnInit()
// Create resource
ID3D12Resource* resource;
#if PLATFORM_WINDOWS
D3D12_HEAP_FLAGS heapFlags = D3D12_HEAP_FLAG_CREATE_NOT_ZEROED;
D3D12_HEAP_FLAGS heapFlags = EnumHasAnyFlags(_desc.Flags, GPUBufferFlags::VertexBuffer | GPUBufferFlags::IndexBuffer) || _desc.InitData ? D3D12_HEAP_FLAG_CREATE_NOT_ZEROED : D3D12_HEAP_FLAG_NONE;
#else
D3D12_HEAP_FLAGS heapFlags = D3D12_HEAP_FLAG_NONE;
#endif

View File

@@ -1304,7 +1304,7 @@ void GPUContextDX12::SetState(GPUPipelineState* state)
}
}
void GPUContextDX12::ClearState()
void GPUContextDX12::ResetState()
{
if (!_commandList)
return;

View File

@@ -201,7 +201,7 @@ public:
void SetScissor(const Rectangle& scissorRect) override;
GPUPipelineState* GetState() const override;
void SetState(GPUPipelineState* state) override;
void ClearState() override;
void ResetState() override;
void FlushState() override;
void Flush() override;
void UpdateBuffer(GPUBuffer* buffer, const void* data, uint32 size, uint32 offset) override;

View File

@@ -628,6 +628,7 @@ bool GPUDeviceDX12::Init()
VALIDATE_DIRECTX_CALL(dxgiAdapter->EnumOutputs(0, dxgiOutput.GetAddressOf()));
DXGI_FORMAT backbufferFormat = RenderToolsDX::ToDxgiFormat(GPU_BACK_BUFFER_PIXEL_FORMAT);
UINT modesCount = 0;
#ifdef _GAMING_XBOX_SCARLETT
VALIDATE_DIRECTX_CALL(dxgiOutput->GetDisplayModeList(backbufferFormat, 0, &modesCount, NULL));
Array<DXGIXBOX_MODE_DESC> modes;
modes.Resize((int32)modesCount);
@@ -642,6 +643,11 @@ bool GPUDeviceDX12::Init()
videoOutput.RefreshRate = Math::Max(videoOutput.RefreshRate, mode.RefreshRate.Numerator / (float)mode.RefreshRate.Denominator);
}
modes.Resize(0);
#else
videoOutput.Width = 1920;
videoOutput.Height = 1080;
videoOutput.RefreshRate = 60;
#endif
#if PLATFORM_GDK
GDKPlatform::Suspended.Bind<GPUDeviceDX12, &GPUDeviceDX12::OnSuspended>(this);

View File

@@ -159,7 +159,7 @@ bool GPUTextureDX12::OnInit()
initialState = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
// Create texture
#if PLATFORM_WINDOWS
#if PLATFORM_WINDOWS && 0
D3D12_HEAP_FLAGS heapFlags = useRTV || useDSV ? D3D12_HEAP_FLAG_CREATE_NOT_ZEROED : D3D12_HEAP_FLAG_NONE;
#else
D3D12_HEAP_FLAGS heapFlags = D3D12_HEAP_FLAG_NONE;

View File

@@ -177,7 +177,7 @@ public:
{
}
void ClearState() override
void ResetState() override
{
}

View File

@@ -1329,7 +1329,7 @@ void GPUContextVulkan::SetState(GPUPipelineState* state)
}
}
void GPUContextVulkan::ClearState()
void GPUContextVulkan::ResetState()
{
ResetRenderTarget();
ResetSR();

View File

@@ -193,7 +193,7 @@ public:
void SetScissor(const Rectangle& scissorRect) override;
GPUPipelineState* GetState() const override;
void SetState(GPUPipelineState* state) override;
void ClearState() override;
void ResetState() override;
void FlushState() override;
void Flush() override;
void UpdateBuffer(GPUBuffer* buffer, const void* data, uint32 size, uint32 offset) override;

View File

@@ -554,10 +554,11 @@ void AnimatedModel::StopSlotAnimation(const StringView& slotName, Animation* ani
{
for (auto& slot : GraphInstance.Slots)
{
if (slot.Animation == anim && slot.Name == slotName)
if ((slot.Animation == anim || anim == nullptr) && slot.Name == slotName)
{
//slot.Animation = nullptr; // TODO: make an immediate version of this method and set the animation to nullptr.
slot.Reset = true;
if (slot.Animation != nullptr)
slot.Reset = true;
break;
}
}
@@ -573,7 +574,7 @@ void AnimatedModel::PauseSlotAnimation(const StringView& slotName, Animation* an
{
for (auto& slot : GraphInstance.Slots)
{
if (slot.Animation == anim && slot.Name == slotName)
if ((slot.Animation == anim || anim == nullptr) && slot.Name == slotName)
{
slot.Pause = true;
break;
@@ -595,7 +596,7 @@ bool AnimatedModel::IsPlayingSlotAnimation(const StringView& slotName, Animation
{
for (auto& slot : GraphInstance.Slots)
{
if (slot.Animation == anim && slot.Name == slotName && !slot.Pause)
if ((slot.Animation == anim || anim == nullptr) && slot.Name == slotName && !slot.Pause)
return true;
}
return false;

View File

@@ -412,8 +412,8 @@ public:
/// Stops the animation playback on the slot in Anim Graph.
/// </summary>
/// <param name="slotName">The name of the slot.</param>
/// <param name="anim">The animation to stop.</param>
API_FUNCTION() void StopSlotAnimation(const StringView& slotName, Animation* anim);
/// <param name="anim">The animation to check. Null to use slot name only.</param>
API_FUNCTION() void StopSlotAnimation(const StringView& slotName, Animation* anim = nullptr);
/// <summary>
/// Pauses all the animations playback on the all slots in Anim Graph.
@@ -424,8 +424,8 @@ public:
/// Pauses the animation playback on the slot in Anim Graph.
/// </summary>
/// <param name="slotName">The name of the slot.</param>
/// <param name="anim">The animation to pause.</param>
API_FUNCTION() void PauseSlotAnimation(const StringView& slotName, Animation* anim);
/// <param name="anim">The animation to check. Null to use slot name only.</param>
API_FUNCTION() void PauseSlotAnimation(const StringView& slotName, Animation* anim = nullptr);
/// <summary>
/// Checks if any animation playback is active on any slot in Anim Graph (not paused).
@@ -436,8 +436,8 @@ public:
/// Checks if the animation playback is active on the slot in Anim Graph (not paused).
/// </summary>
/// <param name="slotName">The name of the slot.</param>
/// <param name="anim">The animation to check.</param>
API_FUNCTION() bool IsPlayingSlotAnimation(const StringView& slotName, Animation* anim);
/// <param name="anim">The animation to check. Null to use slot name only.</param>
API_FUNCTION() bool IsPlayingSlotAnimation(const StringView& slotName, Animation* anim = nullptr);
private:
void ApplyRootMotion(const Transform& rootMotionDelta);

View File

@@ -1123,6 +1123,32 @@ SceneResult SceneLoader::OnBegin(Args& args)
_lastSceneLoadTime = DateTime::Now();
StartFrame = Engine::UpdateCount;
// Validate arguments
if (!args.Data.IsArray())
{
LOG(Error, "Invalid Data member.");
CallSceneEvent(SceneEventType::OnSceneLoadError, nullptr, Guid::Empty);
return SceneResult::Failed;
}
// Peek scene node value (it's the first actor serialized)
SceneId = JsonTools::GetGuid(args.Data[0], "ID");
if (!SceneId.IsValid())
{
LOG(Error, "Invalid scene id.");
CallSceneEvent(SceneEventType::OnSceneLoadError, nullptr, SceneId);
return SceneResult::Failed;
}
// Peek meta
if (args.EngineBuild < 6000)
{
LOG(Error, "Invalid serialized engine build.");
CallSceneEvent(SceneEventType::OnSceneLoadError, nullptr, SceneId);
return SceneResult::Failed;
}
Modifier->EngineBuild = args.EngineBuild;
// Scripting backend should be loaded for the current project before loading scene
if (!Scripting::HasGameModulesLoaded())
{
@@ -1136,27 +1162,7 @@ SceneResult SceneLoader::OnBegin(Args& args)
MessageBox::Show(TEXT("Failed to load scripts.\n\nCannot load scene without game script modules.\n\nSee logs for more info."), TEXT("Missing game modules"), MessageBoxButtons::OK, MessageBoxIcon::Error);
}
#endif
return SceneResult::Failed;
}
// Peek meta
if (args.EngineBuild < 6000)
{
LOG(Error, "Invalid serialized engine build.");
return SceneResult::Failed;
}
if (!args.Data.IsArray())
{
LOG(Error, "Invalid Data member.");
return SceneResult::Failed;
}
Modifier->EngineBuild = args.EngineBuild;
// Peek scene node value (it's the first actor serialized)
SceneId = JsonTools::GetGuid(args.Data[0], "ID");
if (!SceneId.IsValid())
{
LOG(Error, "Invalid scene id.");
CallSceneEvent(SceneEventType::OnSceneLoadError, nullptr, SceneId);
return SceneResult::Failed;
}
@@ -1164,6 +1170,7 @@ SceneResult SceneLoader::OnBegin(Args& args)
if (Level::FindScene(SceneId) != nullptr)
{
LOG(Info, "Scene {0} is already loaded.", SceneId);
CallSceneEvent(SceneEventType::OnSceneLoadError, nullptr, SceneId);
return SceneResult::Failed;
}

View File

@@ -16,7 +16,7 @@ const Char* GetCommandLine(int argc, char* argv[])
const Char* cmdLine;
if (length != 0)
{
Char* str = (Char*)malloc(length * sizeof(Char));
Char* str = (Char*)malloc((length + 1) * sizeof(Char));
cmdLine = str;
for (int i = 1; i < argc; i++)
{

View File

@@ -100,6 +100,35 @@ API_STRUCT(NoDefault, Namespace="FlaxEngine.Networking") struct FLAXENGINE_API N
return Word0 + Word1 != 0;
}
NetworkClientsMask operator&(const NetworkClientsMask& other) const
{
return { Word0 & other.Word0, Word1 & other.Word1 };
}
NetworkClientsMask operator|(const NetworkClientsMask& other) const
{
return { Word0 | other.Word0, Word1 | other.Word1 };
}
NetworkClientsMask operator~() const
{
return { ~Word0, ~Word1 };
}
NetworkClientsMask& operator|=(const NetworkClientsMask& other)
{
Word0 |= other.Word0;
Word1 |= other.Word1;
return *this;
}
NetworkClientsMask& operator&=(const NetworkClientsMask& other)
{
Word0 &= other.Word0;
Word1 &= other.Word1;
return *this;
}
bool operator==(const NetworkClientsMask& other) const
{
return Word0 == other.Word0 && Word1 == other.Word1;

View File

@@ -116,17 +116,6 @@ PACK_STRUCT(struct NetworkMessageObjectRpc
struct NetworkReplicatedObject
{
ScriptingObjectReference<ScriptingObject> Object;
Guid ObjectId;
Guid ParentId;
uint32 OwnerClientId;
uint32 LastOwnerFrame = 0;
NetworkObjectRole Role;
uint8 Spawned : 1;
uint8 Synced : 1;
DataContainer<uint32> TargetClientIds;
INetworkObject* AsNetworkObject;
struct
{
NetworkClientsMask Mask;
@@ -139,6 +128,17 @@ struct NetworkReplicatedObject
}
} RepCache;
ScriptingObjectReference<ScriptingObject> Object;
Guid ObjectId;
Guid ParentId;
DataContainer<uint32> TargetClientIds;
INetworkObject* AsNetworkObject;
uint32 OwnerClientId;
uint32 LastOwnerFrame = 0;
NetworkObjectRole Role;
uint8 Spawned : 1;
uint8 Synced : 1;
NetworkReplicatedObject()
{
Spawned = 0;
@@ -152,12 +152,12 @@ struct NetworkReplicatedObject
bool operator==(const NetworkReplicatedObject& other) const
{
return Object == other.Object;
return ObjectId == other.ObjectId;
}
bool operator==(const ScriptingObject* other) const
{
return Object == other;
return other && ObjectId == other->GetID();
}
bool operator==(const Guid& other) const
@@ -176,6 +176,11 @@ inline uint32 GetHash(const NetworkReplicatedObject& key)
return GetHash(key.ObjectId);
}
inline uint32 GetHash(const ScriptingObject* key)
{
return key ? GetHash(key->GetID()) : 0;
}
struct Serializer
{
NetworkReplicator::SerializeFunc Methods[2];
@@ -698,14 +703,11 @@ void SendReplication(ScriptingObject* obj, NetworkClientsMask targetClients)
return;
auto& item = it->Item;
const bool isClient = NetworkManager::IsClient();
const NetworkClientsMask fullTargetClients = targetClients;
// Skip serialization of objects that none will receive
if (!isClient)
{
BuildCachedTargets(item, targetClients);
if (CachedTargets.Count() == 0)
return;
}
// If server has no recipients, skip early.
if (!isClient && !targetClients)
return;
if (item.AsNetworkObject)
item.AsNetworkObject->OnNetworkSerialize();
@@ -728,18 +730,30 @@ void SendReplication(ScriptingObject* obj, NetworkClientsMask targetClients)
#if USE_NETWORK_REPLICATOR_CACHE
// Process replication cache to skip sending object data if it didn't change
if (item.RepCache.Data.Length() == size &&
item.RepCache.Mask == targetClients &&
Platform::MemoryCompare(item.RepCache.Data.Get(), stream->GetBuffer(), size) == 0)
if (item.RepCache.Data.Length() == size && Platform::MemoryCompare(item.RepCache.Data.Get(), stream->GetBuffer(), size) == 0)
{
return;
// Check if only newly joined clients are missing this data to avoid resending it to everyone
NetworkClientsMask missingClients = targetClients & ~item.RepCache.Mask;
// If data is the same and only the client set changed, replicate to missing clients only
if (!missingClients)
return;
targetClients = missingClients;
}
item.RepCache.Mask = targetClients;
item.RepCache.Mask = fullTargetClients;
item.RepCache.Data.Copy(stream->GetBuffer(), size);
#endif
// TODO: use Unreliable for dynamic objects that are replicated every frame? (eg. player state)
constexpr NetworkChannelType repChannel = NetworkChannelType::Reliable;
// Skip serialization of objects that none will receive
if (!isClient)
{
BuildCachedTargets(item, targetClients);
if (CachedTargets.Count() == 0)
return;
}
// Send object to clients
NetworkMessageObjectReplicate msgData;
msgData.OwnerFrame = NetworkManager::Frame;
@@ -1530,7 +1544,21 @@ void NetworkReplicator::DespawnObject(ScriptingObject* obj)
// Register for despawning (batched during update)
auto& despawn = DespawnQueue.AddOne();
despawn.Id = obj->GetID();
despawn.Targets = item.TargetClientIds;
if (item.TargetClientIds.IsValid())
{
despawn.Targets = item.TargetClientIds;
}
else
{
// Snapshot current recipients to avoid sending despawn to clients that connect later (and never got the spawn)
Array<uint32, InlinedAllocation<8>> clientIds;
for (const NetworkClient* client : NetworkManager::Clients)
{
if (client->State == NetworkConnectionState::Connected && client->ClientId != item.OwnerClientId)
clientIds.Add(client->ClientId);
}
despawn.Targets.Copy(clientIds);
}
// Prevent spawning
for (int32 i = 0; i < SpawnQueue.Count(); i++)
@@ -1823,6 +1851,31 @@ void NetworkInternal::NetworkReplicatorClientConnected(NetworkClient* client)
{
ScopeLock lock(ObjectsLock);
NewClients.Add(client);
// Ensure cached replication acknowledges the new client without resending to others.
// Clear the new client's bit in RepCache and schedule a near-term replication.
const int32 clientIndex = NetworkManager::Clients.Find(client);
if (clientIndex != -1)
{
const uint64 bitMask = 1ull << (uint64)(clientIndex % 64);
const int32 wordIndex = clientIndex / 64;
for (auto it = Objects.Begin(); it.IsNotEnd(); ++it)
{
auto& item = it->Item;
ScriptingObject* obj = item.Object.Get();
if (!obj || !item.Spawned || item.Role != NetworkObjectRole::OwnedAuthoritative)
continue;
// Mark this client as missing cached data
uint64* word = wordIndex == 0 ? &item.RepCache.Mask.Word0 : &item.RepCache.Mask.Word1;
*word &= ~bitMask;
// Force next replication tick for this object so the new client gets data promptly
if (Hierarchy)
Hierarchy->DirtyObject(obj);
}
}
ASSERT(sizeof(NetworkClientsMask) * 8 >= (uint32)NetworkManager::Clients.Count()); // Ensure that clients mask can hold all of clients
}
@@ -2275,7 +2328,9 @@ void NetworkInternal::OnNetworkMessageObjectDespawn(NetworkEvent& event, Network
}
else
{
NETWORK_REPLICATOR_LOG(Error, "[NetworkReplicator] Failed to despawn object {}", objectId);
// If this client never had the object (eg. it was targeted to other clients only), drop the message quietly
DespawnedObjects.Add(objectId);
NETWORK_REPLICATOR_LOG(Warning, "[NetworkReplicator] Failed to despawn object {}", objectId);
}
}

View File

@@ -482,9 +482,15 @@ void ParticleEmitterGraphCPUExecutor::ProcessGroupFunction(Box* box, Node* node,
// Function Input
case 1:
{
// Skip when graph is too small (eg. preview) and fallback with default value from the function graph
if (context.GraphStack.Count() < 2)
{
value = tryGetValue(node->TryGetBox(1), Value::Zero);
break;
}
// Find the function call
Node* functionCallNode = nullptr;
ASSERT(context.GraphStack.Count() >= 2);
ParticleEmitterGraphCPU* graph;
for (int32 i = context.CallStackSize - 1; i >= 0; i--)
{

View File

@@ -52,6 +52,7 @@ Array<User*, FixedAllocation<8>> PlatformBase::Users;
Delegate<User*> PlatformBase::UserAdded;
Delegate<User*> PlatformBase::UserRemoved;
void* OutOfMemoryBuffer = nullptr;
volatile int64 FatalReporting = 0;
const Char* ToString(NetworkConnectionType value)
{
@@ -330,11 +331,20 @@ int32 PlatformBase::GetCacheLineSize()
void PlatformBase::Fatal(const StringView& msg, void* context, FatalErrorType error)
{
// Let only one thread to report the error (and wait for it to end to have valid log before crash)
RETRY:
if (Platform::InterlockedCompareExchange(&FatalReporting, 1, 0) != 0)
{
Platform::Sleep(1);
goto RETRY;
}
// Check if is already during fatal state
if (Engine::FatalError != FatalErrorType::None)
{
// Just send one more error to the log and back
LOG(Error, "Error after fatal error: {0}", msg);
Platform::AtomicStore(&FatalReporting, 0);
return;
}
@@ -453,6 +463,8 @@ void PlatformBase::Fatal(const StringView& msg, void* context, FatalErrorType er
}
#endif
Platform::AtomicStore(&FatalReporting, 0);
// Show error message
if (Engine::ReportCrash.IsBinded())
Engine::ReportCrash(msg, context);

View File

@@ -2993,6 +2993,7 @@ bool LinuxPlatform::SetEnvironmentVariable(const String& name, const String& val
return setenv(StringAsANSI<>(*name).Get(), StringAsANSI<>(*value).Get(), true) != 0;
}
#if !PLATFORM_SDL
int32 LinuxPlatform::CreateProcess(CreateProcessSettings& settings)
{
LOG(Info, "Command: {0} {1}", settings.FileName, settings.Arguments);
@@ -3106,6 +3107,7 @@ int32 LinuxPlatform::CreateProcess(CreateProcessSettings& settings)
return returnCode;
}
#endif
void* LinuxPlatform::LoadLibrary(const Char* filename)
{

View File

@@ -148,7 +148,9 @@ public:
static void GetEnvironmentVariables(Dictionary<String, String, HeapAllocation>& result);
static bool GetEnvironmentVariable(const String& name, String& value);
static bool SetEnvironmentVariable(const String& name, const String& value);
#if !PLATFORM_SDL
static int32 CreateProcess(CreateProcessSettings& settings);
#endif
static void* LoadLibrary(const Char* filename);
static void FreeLibrary(void* handle);
static void* GetProcAddress(void* handle, const char* symbol);

View File

@@ -18,6 +18,7 @@
#include "Engine/Graphics/PixelFormatSampler.h"
#include "Engine/Graphics/Textures/TextureData.h"
#include "IncludeX11.h"
#include "ThirdParty/X11/Xutil.h"
// ICCCM
#define WM_NormalState 1L // window normal state
@@ -178,6 +179,20 @@ LinuxWindow::LinuxWindow(const CreateWindowSettings& settings)
X11::XSetTransientForHint(display, window, (X11::Window)((LinuxWindow*)settings.Parent)->GetNativePtr());
}
// Provides class hint for WMs like Hyprland to hook onto and apply window rules
X11::XClassHint* classHint = X11::XAllocClassHint();
if (classHint)
{
const char* className = settings.IsRegularWindow ? "FlexEditor" : "FlaxPopup";
classHint->res_name = const_cast<char*>(className);
classHint->res_class = const_cast<char*>(className);
X11::XSetClassHint(display, window, classHint);
XFree(classHint);
}
_dpi = Platform::GetDpi();
_dpiScale = (float)_dpi / (float)DefaultDPI;

View File

@@ -437,6 +437,7 @@ Window* MacPlatform::CreateWindow(const CreateWindowSettings& settings)
#endif
#if !PLATFORM_SDL
int32 MacPlatform::CreateProcess(CreateProcessSettings& settings)
{
LOG(Info, "Command: {0} {1}", settings.FileName, settings.Arguments);
@@ -576,5 +577,6 @@ int32 MacPlatform::CreateProcess(CreateProcessSettings& settings)
return returnCode;
}
#endif
#endif

View File

@@ -27,7 +27,9 @@ public:
static Rectangle GetVirtualDesktopBounds();
static String GetMainDirectory();
static Window* CreateWindow(const CreateWindowSettings& settings);
#if !PLATFORM_SDL
static int32 CreateProcess(CreateProcessSettings& settings);
#endif
};
#endif

View File

@@ -8,18 +8,19 @@
#include "Engine/Input/Input.h"
#include "Engine/Input/Mouse.h"
#include "Engine/Platform/BatteryInfo.h"
#include "Engine/Platform/CreateProcessSettings.h"
#include "Engine/Platform/WindowsManager.h"
#include "Engine/Platform/SDL/SDLInput.h"
#include "Engine/Engine/Engine.h"
#include <SDL3/SDL_hints.h>
#include <SDL3/SDL_init.h>
#include <SDL3/SDL_locale.h>
#include <SDL3/SDL_misc.h>
#include <SDL3/SDL_power.h>
#include <SDL3/SDL_process.h>
#include <SDL3/SDL_revision.h>
#include <SDL3/SDL_system.h>
#include <SDL3/SDL_version.h>
#include <SDL3/SDL_locale.h>
#if PLATFORM_LINUX
#include "Engine/Engine/CommandLine.h"
@@ -316,4 +317,152 @@ Window* SDLPlatform::CreateWindow(const CreateWindowSettings& settings)
return New<SDLWindow>(settings);
}
bool ReadStream(SDL_IOStream*& stream, char* buffer, int32 bufferLength, int32& bufferPosition, LogType logType, CreateProcessSettings& settings)
{
bool flushBuffer = false;
bool success = true;
int32 read = SDL_ReadIO(stream, buffer + bufferPosition, bufferLength - bufferPosition - 1);
if (read == 0)
{
SDL_IOStatus status = SDL_GetIOStatus(stream);
if (status != SDL_IO_STATUS_NOT_READY && status != SDL_IO_STATUS_EOF)
success = false;
if (status != SDL_IO_STATUS_NOT_READY)
{
stream = nullptr;
flushBuffer = true;
}
}
else
{
int32 startPosition = bufferPosition;
bufferPosition += read;
if (bufferPosition == bufferLength - 1)
{
flushBuffer = true;
buffer[bufferPosition++] = '\n'; // Make sure to flush fully filled buffer
}
else
{
for (int i = startPosition; i < bufferPosition; ++i)
{
if (buffer[i] == '\n')
{
flushBuffer = true;
break;
}
}
}
}
if (flushBuffer)
{
int32 start = 0;
for (int i = 0; i < bufferPosition; ++i)
{
if (buffer[i] != '\n')
continue;
String str(&buffer[start], i - start + 1);
#if LOG_ENABLE
if (settings.LogOutput)
Log::Logger::Write(logType, StringView(str.Get(), str.Length() - 1));
#endif
if (settings.SaveOutput)
settings.Output.Add(str.Get(), str.Length());
start = i + 1;
}
int32 length = bufferPosition - start;
if (length > 0)
{
// TODO: Use memmove here? Overlapped memory regions with memcpy is undefined behaviour
char temp[2048];
Platform::MemoryCopy(temp, buffer + start, length);
Platform::MemoryCopy(buffer, temp, length);
bufferPosition = length;
}
else
bufferPosition = 0;
}
return success;
}
int32 SDLPlatform::CreateProcess(CreateProcessSettings& settings)
{
LOG(Info, "Command: {0} {1}", settings.FileName, settings.Arguments);
if (settings.WorkingDirectory.HasChars())
LOG(Info, "Working directory: {0}", settings.WorkingDirectory);
int32 result = 0;
const bool captureStdOut = settings.LogOutput || settings.SaveOutput;
const StringAnsi cmdLine = StringAnsi::Format("\"{0}\" {1}", StringAnsi(settings.FileName), StringAnsi(settings.Arguments));
const char* cmd[] = { "sh", "-c", cmdLine.Get(), (char *)0 };
StringAnsi workingDirectory(settings.WorkingDirectory);
#if PLATFORM_WINDOWS
bool background = !settings.WaitForEnd || settings.HiddenWindow; // This also hides the window on Windows
#else
bool background = !settings.WaitForEnd;
#endif
// Populate environment with current values from parent environment.
// SDL does not populate the environment with the latest values but with a snapshot captured during initialization.
Dictionary<String, String> envDictionary;
GetEnvironmentVariables(envDictionary);
SDL_Environment* env = SDL_CreateEnvironment(false);
for (auto iter = envDictionary.Begin(); iter != envDictionary.End(); ++iter)
SDL_SetEnvironmentVariable(env, StringAnsi(iter->Key).Get(), StringAnsi(iter->Value).Get(), true);
for (auto iter = settings.Environment.Begin(); iter != settings.Environment.End(); ++iter)
SDL_SetEnvironmentVariable(env, StringAnsi(iter->Key).Get(), StringAnsi(iter->Value).Get(), true);
SDL_PropertiesID props = SDL_CreateProperties();
SDL_SetPointerProperty(props, SDL_PROP_PROCESS_CREATE_ARGS_POINTER, cmd);
SDL_SetPointerProperty(props, SDL_PROP_PROCESS_CREATE_ENVIRONMENT_POINTER, env);
SDL_SetBooleanProperty(props, SDL_PROP_PROCESS_CREATE_BACKGROUND_BOOLEAN, background);
if (workingDirectory.HasChars())
SDL_SetStringProperty(props, SDL_PROP_PROCESS_CREATE_WORKING_DIRECTORY_STRING, workingDirectory.Get());
if (captureStdOut)
{
SDL_SetNumberProperty(props, SDL_PROP_PROCESS_CREATE_STDOUT_NUMBER, SDL_PROCESS_STDIO_APP);
SDL_SetNumberProperty(props, SDL_PROP_PROCESS_CREATE_STDERR_NUMBER, SDL_PROCESS_STDIO_APP);
}
SDL_Process* process = SDL_CreateProcessWithProperties(props);
SDL_DestroyProperties(props);
SDL_DestroyEnvironment(env);
if (process == nullptr)
{
LOG(Error, "Failed to run process {}: {}", String(settings.FileName).Get(), String(SDL_GetError()));
return -1;
}
props = SDL_GetProcessProperties(process);
int32 pid = SDL_GetNumberProperty(props, SDL_PROP_PROCESS_PID_NUMBER, 0);
SDL_IOStream* stdoutStream = nullptr;
SDL_IOStream* stderrStream = nullptr;
if (captureStdOut)
{
stdoutStream = static_cast<SDL_IOStream*>(SDL_GetPointerProperty(props, SDL_PROP_PROCESS_STDOUT_POINTER, nullptr));
stderrStream = static_cast<SDL_IOStream*>(SDL_GetPointerProperty(props, SDL_PROP_PROCESS_STDERR_POINTER, nullptr));
}
// Handle process output in realtime
char stdoutBuffer[2049];
int32 stdoutPosition = 0;
char stderrBuffer[2049];
int32 stderrPosition = 0;
while (stdoutStream != nullptr && stderrStream != nullptr)
{
if (stdoutStream != nullptr && !ReadStream(stdoutStream, stdoutBuffer, sizeof(stdoutBuffer), stdoutPosition, LogType::Info, settings))
LOG(Warning, "Failed to read process {} stdout: {}", pid, String(SDL_GetError()));
if (stderrStream != nullptr && !ReadStream(stderrStream, stderrBuffer, sizeof(stderrBuffer), stderrPosition, LogType::Error, settings))
LOG(Warning, "Failed to read process {} stderr: {}", pid, String(SDL_GetError()));
Sleep(1);
}
if (settings.WaitForEnd)
SDL_WaitProcess(process, true, &result);
SDL_DestroyProcess(process);
return result;
}
#endif

View File

@@ -87,6 +87,7 @@ public:
static Rectangle GetMonitorBounds(const Float2& screenPos);
static Rectangle GetVirtualDesktopBounds();
static Window* CreateWindow(const CreateWindowSettings& settings);
static int32 CreateProcess(CreateProcessSettings& settings);
};
#endif

View File

@@ -1121,6 +1121,7 @@ bool IsProcRunning(HANDLE handle)
return WaitForSingleObject(handle, 0) == WAIT_TIMEOUT;
}
#if !PLATFORM_SDL
void ReadPipe(HANDLE pipe, Array<char>& rawData, Array<Char>& logData, LogType logType, CreateProcessSettings& settings)
{
// Check if any data is ready to read
@@ -1329,7 +1330,6 @@ int32 WindowsPlatform::CreateProcess(CreateProcessSettings& settings)
return result;
}
#if !PLATFORM_SDL
Window* WindowsPlatform::CreateWindow(const CreateWindowSettings& settings)
{
return New<WindowsWindow>(settings);

View File

@@ -81,8 +81,8 @@ public:
static void GetEnvironmentVariables(Dictionary<String, String, HeapAllocation>& result);
static bool GetEnvironmentVariable(const String& name, String& value);
static bool SetEnvironmentVariable(const String& name, const String& value);
static int32 CreateProcess(CreateProcessSettings& settings);
#if !PLATFORM_SDL
static int32 CreateProcess(CreateProcessSettings& settings);
static Window* CreateWindow(const CreateWindowSettings& settings);
#endif
static void* LoadLibrary(const Char* filename);

View File

@@ -375,6 +375,7 @@ void PostProcessingPass::Render(RenderContext& renderContext, GPUTexture* input,
RENDER_TARGET_POOL_SET_NAME(bloomBuffer1, "PostProcessing.Bloom");
RENDER_TARGET_POOL_SET_NAME(bloomBuffer2, "PostProcessing.Bloom");
// TODO: skip this clear? or do it at once for the whole textures (2 calls instead of per-mip)
for (int32 mip = 0; mip < bloomMipCount; mip++)
{
context->Clear(bloomBuffer1->View(0, mip), Color::Transparent);

View File

@@ -509,7 +509,7 @@ void ProbesRendererService::OnRender(RenderTask* task, GPUContext* context)
// Render frame
Renderer::Render(_task);
context->ClearState();
context->ResetState();
// Copy frame to cube face
{
@@ -568,7 +568,7 @@ void ProbesRendererService::OnRender(RenderTask* task, GPUContext* context)
}
// Cleanup
context->ClearState();
context->ResetState();
if (_workStep < 7)
return; // Continue rendering next frame

View File

@@ -920,6 +920,7 @@ void RenderList::ExecuteDrawCalls(const RenderContext& renderContext, DrawCallsL
constexpr int32 vbMax = ARRAY_COUNT(DrawCall::Geometry.VertexBuffers);
if (useInstancing)
{
context->UpdateCB(perDrawCB, &perDraw);
GPUBuffer* vb[vbMax + 1];
uint32 vbOffsets[vbMax + 1];
vb[3] = _instanceBuffer.GetBuffer(); // Pass object index in a vertex stream at slot 3 (used by VS in Surface.shader)
@@ -1057,7 +1058,7 @@ void RenderList::ExecuteDrawCalls(const RenderContext& renderContext, DrawCallsL
materialBinds += list.PreBatchedDrawCalls.Count();
if (list.Batches.IsEmpty() && list.Indices.Count() != 0)
{
// Draw calls list has bot been batched so execute draw calls separately
// Draw calls list has not been batched so execute draw calls separately
for (int32 j = 0; j < list.Indices.Count(); j++)
{
perDraw.DrawObjectIndex = listData[j];

View File

@@ -273,7 +273,7 @@ struct DrawCallsList
/// <summary>
/// True if draw calls batches list can be rendered using hardware instancing, otherwise false.
/// </summary>
bool CanUseInstancing;
bool CanUseInstancing = true;
void Clear();
bool IsEmpty() const;

View File

@@ -200,7 +200,7 @@ void Renderer::Render(SceneRenderTask* task)
// Prepare GPU context
auto context = GPUDevice::Instance->GetMainContext();
context->ClearState();
context->ResetState();
context->FlushState();
const Viewport viewport = task->GetViewport();
context->SetViewportAndScissors(viewport);

View File

@@ -2136,6 +2136,53 @@ static void* OnMonoDlFallbackClose(void* handle, void* user_data)
#endif
#ifdef USE_MONO_AOT_MODULE
#include "Engine/Threading/ThreadPoolTask.h"
#include "Engine/Engine/EngineService.h"
class MonoAotPreloadTask : public ThreadPoolTask
{
public:
bool Run() override;
};
// Preloads in-build AOT dynamic module in async
class MonoAotPreloadService : public EngineService
{
public:
volatile int64 Ready = 0;
void* Library = nullptr;
MonoAotPreloadService()
: EngineService(TEXT("AOT Preload"), -800)
{
}
bool Init() override
{
New<MonoAotPreloadTask>()->Start();
return false;
}
};
MonoAotPreloadService MonoAotPreloadServiceInstance;
bool MonoAotPreloadTask::Run()
{
// Load AOT module
Stopwatch aotModuleLoadStopwatch;
//LOG(Info, "Loading Mono AOT module...");
MonoAotPreloadServiceInstance.Library = Platform::LoadLibrary(TEXT(USE_MONO_AOT_MODULE));
aotModuleLoadStopwatch.Stop();
LOG(Info, "Mono AOT module loaded in {0}ms", aotModuleLoadStopwatch.GetMilliseconds());
Platform::AtomicStore(&MonoAotPreloadServiceInstance.Ready, 1);
return false;
}
#endif
bool InitHostfxr()
{
#if DOTNET_HOST_MONO_DEBUG
@@ -2166,10 +2213,12 @@ bool InitHostfxr()
#endif
#ifdef USE_MONO_AOT_MODULE
// Load AOT module
Stopwatch aotModuleLoadStopwatch;
LOG(Info, "Loading Mono AOT module...");
void* libAotModule = Platform::LoadLibrary(TEXT(USE_MONO_AOT_MODULE));
// Wait for AOT module preloading
while (Platform::AtomicRead(&MonoAotPreloadServiceInstance.Ready) == 0)
Platform::Yield();
// Initialize AOT module
void* libAotModule = MonoAotPreloadServiceInstance.Library;
if (libAotModule == nullptr)
{
LOG(Error, "Failed to laod Mono AOT module (" TEXT(USE_MONO_AOT_MODULE) ")");
@@ -2192,8 +2241,6 @@ bool InitHostfxr()
mono_aot_register_module((void**)modules[i]);
}
Allocator::Free(modules);
aotModuleLoadStopwatch.Stop();
LOG(Info, "Mono AOT module loaded in {0}ms", aotModuleLoadStopwatch.GetMilliseconds());
#endif
// Setup debugger

View File

@@ -33,6 +33,13 @@ public:
{
}
ScriptingObjectReferenceBase(ScriptingObjectReferenceBase&& other) noexcept
: _object(nullptr)
{
OnSet(other._object);
other.OnSet(nullptr);
}
/// <summary>
/// Initializes a new instance of the <see cref="ScriptingObjectReferenceBase"/> class.
/// </summary>
@@ -96,6 +103,16 @@ protected:
void OnSet(ScriptingObject* object);
void OnDeleted(ScriptingObject* obj);
ScriptingObjectReferenceBase& operator=(ScriptingObjectReferenceBase&& other) noexcept
{
if (this != &other)
{
OnSet(other._object);
other.OnSet(nullptr);
}
return *this;
}
};
/// <summary>
@@ -133,6 +150,11 @@ public:
{
}
ScriptingObjectReference(ScriptingObjectReference&& other) noexcept
: ScriptingObjectReferenceBase(MoveTemp(other))
{
}
/// <summary>
/// Finalizes an instance of the <see cref="ScriptingObjectReference"/> class.
/// </summary>
@@ -173,6 +195,12 @@ public:
return *this;
}
ScriptingObjectReference& operator=(ScriptingObjectReference&& other) noexcept
{
ScriptingObjectReferenceBase::operator=(MoveTemp(other));
return *this;
}
FORCE_INLINE ScriptingObjectReference& operator=(const Guid& id)
{
OnSet(static_cast<ScriptingObject*>(FindObject(id, T::GetStaticClass())));

View File

@@ -76,16 +76,19 @@ ShaderCompilerDX::ShaderCompilerDX(ShaderProfile profile, PlatformType platform,
{
IDxcCompiler3* compiler = nullptr;
IDxcLibrary* library = nullptr;
IDxcContainerBuilder* builder = nullptr;
IDxcContainerReflection* containerReflection = nullptr;
DxcCreateInstanceProc createInstance = dxcCreateInstanceProc ? (DxcCreateInstanceProc)dxcCreateInstanceProc : &DxcCreateInstance;
if (FAILED(createInstance(CLSID_DxcCompiler, __uuidof(compiler), reinterpret_cast<void**>(&compiler))) ||
FAILED(createInstance(CLSID_DxcLibrary, __uuidof(library), reinterpret_cast<void**>(&library))) ||
FAILED(createInstance(CLSID_DxcContainerBuilder, __uuidof(builder), reinterpret_cast<void**>(&builder))) ||
FAILED(createInstance(CLSID_DxcContainerReflection, __uuidof(containerReflection), reinterpret_cast<void**>(&containerReflection))))
{
LOG(Error, "DxcCreateInstance failed");
}
_compiler = compiler;
_library = library;
_builder = builder;
_containerReflection = containerReflection;
static HashSet<void*> PrintVersions;
if (PrintVersions.Add(createInstance))
@@ -103,14 +106,13 @@ ShaderCompilerDX::ShaderCompilerDX(ShaderProfile profile, PlatformType platform,
ShaderCompilerDX::~ShaderCompilerDX()
{
auto compiler = (IDxcCompiler2*)_compiler;
if (compiler)
if (auto compiler = (IDxcCompiler2*)_compiler)
compiler->Release();
auto library = (IDxcLibrary*)_library;
if (library)
if (auto library = (IDxcLibrary*)_library)
library->Release();
auto containerReflection = (IDxcContainerReflection*)_containerReflection;
if (containerReflection)
if (auto builder = (IDxcContainerBuilder*)_builder)
builder->Release();
if (auto containerReflection = (IDxcContainerReflection*)_containerReflection)
containerReflection->Release();
}
@@ -254,7 +256,7 @@ bool ShaderCompilerDX::CompileShader(ShaderFunctionMeta& meta, WritePermutationD
}
// Get the output
ComPtr<IDxcBlob> shaderBuffer = nullptr;
ComPtr<IDxcBlob> shaderBuffer;
if (FAILED(results->GetResult(&shaderBuffer)))
{
LOG(Error, "IDxcOperationResult::GetResult failed.");
@@ -460,6 +462,28 @@ bool ShaderCompilerDX::CompileShader(ShaderFunctionMeta& meta, WritePermutationD
}
}
// Strip reflection data
if (!options->GenerateDebugData)
{
if (auto builder = (IDxcContainerBuilder*)_builder)
{
if (builder->Load(shaderBuffer) == S_OK)
{
builder->RemovePart(DXC_PART_PDB);
builder->RemovePart(DXC_PART_REFLECTION_DATA);
ComPtr<IDxcOperationResult> serializeResult;
if (builder->SerializeContainer(&serializeResult) == S_OK)
{
ComPtr<IDxcBlob> optimizedShaderBuffer;
if (SUCCEEDED(serializeResult->GetResult(&optimizedShaderBuffer)))
{
shaderBuffer = optimizedShaderBuffer;
}
}
}
}
}
if (WriteShaderFunctionPermutation(_context, meta, permutationIndex, bindings, &header, sizeof(header), shaderBuffer->GetBufferPointer(), (int32)shaderBuffer->GetBufferSize()))
return true;

View File

@@ -15,6 +15,7 @@ private:
Array<char> _funcNameDefineBuffer;
void* _compiler;
void* _library;
void* _builder;
void* _containerReflection;
public:

View File

@@ -278,6 +278,17 @@ bool ShaderCompiler::WriteShaderFunctionPermutation(ShaderCompilationContext* co
return false;
}
bool ShaderCompiler::WriteShaderFunctionPermutation(ShaderCompilationContext* context, ShaderFunctionMeta& meta, int32 permutationIndex, const ShaderBindings& bindings, const void* header, int32 headerSize, const void* cache1, int32 cache1Size, const void* cache2, int32 cache2Size)
{
auto output = context->Output;
output->Write((uint32)(cache1Size + cache2Size + headerSize));
output->WriteBytes(header, headerSize);
output->WriteBytes(cache1, cache1Size);
output->WriteBytes(cache2, cache2Size);
output->Write(bindings);
return false;
}
bool ShaderCompiler::WriteShaderFunctionPermutation(ShaderCompilationContext* context, ShaderFunctionMeta& meta, int32 permutationIndex, const ShaderBindings& bindings, const void* cache, int32 cacheSize)
{
auto output = context->Output;

View File

@@ -108,6 +108,7 @@ protected:
static bool WriteShaderFunctionBegin(ShaderCompilationContext* context, ShaderFunctionMeta& meta);
static bool WriteShaderFunctionPermutation(ShaderCompilationContext* context, ShaderFunctionMeta& meta, int32 permutationIndex, const ShaderBindings& bindings, const void* header, int32 headerSize, const void* cache, int32 cacheSize);
static bool WriteShaderFunctionPermutation(ShaderCompilationContext* context, ShaderFunctionMeta& meta, int32 permutationIndex, const ShaderBindings& bindings, const void* header, int32 headerSize, const void* cache1, int32 cache1Size, const void* cache2, int32 cache2Size);
static bool WriteShaderFunctionPermutation(ShaderCompilationContext* context, ShaderFunctionMeta& meta, int32 permutationIndex, const ShaderBindings& bindings, const void* cache, int32 cacheSize);
static bool WriteShaderFunctionEnd(ShaderCompilationContext* context, ShaderFunctionMeta& meta);
static bool WriteCustomDataVS(ShaderCompilationContext* context, ShaderFunctionMeta& meta, int32 permutationIndex, const Array<ShaderMacro>& macros, void* additionalData);

View File

@@ -376,7 +376,7 @@ void ShadowsOfMordor::Builder::onJobRender(GPUContext* context)
EnableLightmapsUsage = _giBounceRunningIndex != 0;
//
Renderer::Render(_task);
context->ClearState();
context->ResetState();
//
IsRunningRadiancePass = false;
EnableLightmapsUsage = true;
@@ -515,7 +515,7 @@ void ShadowsOfMordor::Builder::onJobRender(GPUContext* context)
}
// Cleanup after rendering
context->ClearState();
context->ResetState();
// Mark job as done
Platform::AtomicStore(&_wasJobDone, 1);

View File

@@ -27,6 +27,19 @@ void CheckBitArray(const BitArray<AllocationType>& array)
TEST_CASE("Array")
{
SECTION("Test Capacity")
{
// Ensure correct collections capacity growing to meet proper memory usage vs safe slack
CHECK(AllocationUtils::CalculateCapacityGrow(1, 0) == 8);
CHECK(AllocationUtils::CalculateCapacityGrow(7, 0) == 8);
CHECK(AllocationUtils::CalculateCapacityGrow(1, 16) == 16);
CHECK(AllocationUtils::CalculateCapacityGrow(31, 0) == 32);
CHECK(AllocationUtils::CalculateCapacityGrow(32, 0) == 32);
CHECK(AllocationUtils::CalculateCapacityGrow(1000, 0) == 1024);
CHECK(AllocationUtils::CalculateCapacityGrow(1024, 0) == 1024);
CHECK(AllocationUtils::CalculateCapacityGrow(1025, 0) == 2048);
}
SECTION("Test Allocators")
{
Array<int32> a1;

View File

@@ -790,9 +790,18 @@ void MaterialGenerator::ProcessGroupFunction(Box* box, Node* node, Value& value)
// Function Input
case 1:
{
// Check the stack count. If only 1 graph is present,
// we are processing the graph in isolation (e.g., in the Editor Preview).
// In this case, we skip the caller-finding logic and use the node's default value.
if (_graphStack.Count() < 2)
{
// Use the default value from the function input node's box (usually box 1)
value = tryGetValue(node->TryGetBox(1), Value::Zero);
break;
}
// Find the function call
Node* functionCallNode = nullptr;
ASSERT(_graphStack.Count() >= 2);
Graph* graph;
for (int32 i = _callStack.Count() - 1; i >= 0; i--)
{

View File

@@ -303,6 +303,12 @@ namespace FlaxEngine.GUI
[EditorDisplay("Text Style"), EditorOrder(2023), ExpandGroups]
public Color TextColor { get; set; }
/// <summary>
/// Gets or sets the color used to display highlighted text.
/// </summary>
[EditorDisplay("Text Style"), EditorOrder(2024), ExpandGroups]
public Color TextColorHighlighted { get; set; }
/// <summary>
/// Gets or sets the horizontal text alignment within the control bounds.
/// </summary>
@@ -386,6 +392,7 @@ namespace FlaxEngine.GUI
var style = Style.Current;
Font = new FontReference(style.FontMedium);
TextColor = style.Foreground;
TextColorHighlighted = style.Foreground;
BackgroundColor = style.BackgroundNormal;
BackgroundColorHighlighted = BackgroundColor;
BackgroundColorSelected = BackgroundColor;
@@ -587,8 +594,8 @@ namespace FlaxEngine.GUI
X = margin,
Size = new Float2(size.X - margin, size.Y),
Font = Font,
TextColor = Color.White * 0.9f,
TextColorHighlighted = Color.White,
TextColor = TextColor * 0.9f,
TextColorHighlighted = TextColorHighlighted,
HorizontalAlignment = HorizontalAlignment,
VerticalAlignment = VerticalAlignment,
Text = _items[i],
@@ -749,7 +756,7 @@ namespace FlaxEngine.GUI
// Draw text of the selected item
var textRect = new Rectangle(margin, 0, clientRect.Width - boxSize - 2.0f * margin, clientRect.Height);
Render2D.PushClip(textRect);
var textColor = TextColor;
var textColor = (IsMouseOver || IsNavFocused) ? TextColorHighlighted : TextColor;
string text = _items[_selectedIndex];
string format = TextFormat != null ? TextFormat : null;
if (!string.IsNullOrEmpty(format))

View File

@@ -146,6 +146,8 @@ void ShaderGenerator::ProcessGroupMath(Box* box, Node* node, Value& value)
Box* b2 = node->GetBox(1);
Value v1 = tryGetValue(b1, 0, Value::Zero);
Value v2 = tryGetValue(b2, 1, Value::Zero);
if (SanitizeMathValue(v1, node, b1, &value))
break;
if (b1->HasConnection())
v2 = v2.Cast(v1.Type);
else
@@ -251,7 +253,10 @@ void ShaderGenerator::ProcessGroupMath(Box* box, Node* node, Value& value)
// Lerp
case 25:
{
Value a = tryGetValue(node->GetBox(0), 0, Value::Zero);
auto boxA = node->GetBox(0);
Value a = tryGetValue(boxA, 0, Value::Zero);
if (SanitizeMathValue(a, node, boxA, &value))
break;
Value b = tryGetValue(node->GetBox(1), 1, Value::One).Cast(a.Type);
Value alpha = tryGetValue(node->GetBox(2), 2, Value::Zero).Cast(ValueType::Float);
String text = String::Format(TEXT("lerp({0}, {1}, {2})"), a.Value, b.Value, alpha.Value);
@@ -1364,6 +1369,20 @@ SerializedMaterialParam& ShaderGenerator::findOrAddGlobalSDF()
return param;
}
bool ShaderGenerator::SanitizeMathValue(Value& value, Node* node, Box* box, Value* resultOnInvalid)
{
bool invalid = value.Type == VariantType::Object;
if (invalid)
{
OnError(node, box, TEXT("Invalid input type for math operation"));
if (resultOnInvalid)
*resultOnInvalid = Value::Zero;
else
value = Value::Zero;
}
return invalid;
}
String ShaderGenerator::getLocalName(int32 index)
{
return TEXT("local") + StringUtils::ToString(index);

View File

@@ -255,6 +255,8 @@ protected:
SerializedMaterialParam& findOrAddTextureGroupSampler(int32 index);
SerializedMaterialParam& findOrAddGlobalSDF();
bool SanitizeMathValue(Value& value, Node* node, Box* box, Value* resultOnInvalid = nullptr);
static String getLocalName(int32 index);
static String getParamName(int32 index);
};

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
// Copyright (c) Wojciech Figat. All rights reserved.
package com.flaxengine;

View File

@@ -20,7 +20,7 @@
*/
/**
* Main include header for the SDL library, version 3.2.24
* Main include header for the SDL library, version 3.3.4
*
* It is almost always best to include just this one header instead of
* picking out individual headers included here. There are exceptions to
@@ -42,6 +42,7 @@
#include <SDL3/SDL_clipboard.h>
#include <SDL3/SDL_cpuinfo.h>
#include <SDL3/SDL_dialog.h>
#include <SDL3/SDL_dlopennote.h>
#include <SDL3/SDL_endian.h>
#include <SDL3/SDL_error.h>
#include <SDL3/SDL_events.h>

View File

@@ -132,14 +132,11 @@ extern "C" {
#define SDL_TriggerBreakpoint() __debugbreak()
#elif defined(_MSC_VER) && defined(_M_IX86)
#define SDL_TriggerBreakpoint() { _asm { int 0x03 } }
#elif defined(ANDROID)
#include <assert.h>
#define SDL_TriggerBreakpoint() assert(0)
#elif SDL_HAS_BUILTIN(__builtin_debugtrap)
#define SDL_TriggerBreakpoint() __builtin_debugtrap()
#elif SDL_HAS_BUILTIN(__builtin_trap)
#define SDL_TriggerBreakpoint() __builtin_trap()
#elif (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__))
#elif (defined(__GNUC__) || defined(__clang__) || defined(__TINYC__)) && (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" )
@@ -179,12 +176,48 @@ extern "C" {
# define SDL_FUNCTION "???"
#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.
@@ -363,7 +396,7 @@ extern SDL_DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *
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_FILE, SDL_LINE); \
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) { \

View File

@@ -596,6 +596,24 @@ extern SDL_DECLSPEC Uint32 SDLCALL SDL_SetAtomicU32(SDL_AtomicU32 *a, Uint32 v);
*/
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.
*

View File

@@ -1024,7 +1024,8 @@ 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.
* 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.
@@ -1066,6 +1067,17 @@ extern SDL_DECLSPEC SDL_AudioStream * SDLCALL SDL_CreateAudioStream(const SDL_Au
/**
* 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.
@@ -1076,6 +1088,9 @@ extern SDL_DECLSPEC SDL_AudioStream * SDLCALL SDL_CreateAudioStream(const SDL_Au
*/
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.
*
@@ -1152,14 +1167,14 @@ extern SDL_DECLSPEC float SDLCALL SDL_GetAudioStreamFrequencyRatio(SDL_AudioStre
*
* The frequency ratio is used to adjust the rate at which input data is
* consumed. Changing this effectively modifies the speed and pitch of the
* audio. A value greater than 1.0 will play the audio faster, and at a higher
* pitch. A value less than 1.0 will play the audio slower, and at a lower
* pitch.
* 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 the frequency ratio is being changed.
* \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
@@ -1321,7 +1336,7 @@ extern SDL_DECLSPEC int * SDLCALL SDL_GetAudioStreamOutputChannelMap(SDL_AudioSt
* \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!
* different thread at the same time, though!
*
* \since This function is available since SDL 3.2.0.
*
@@ -1335,7 +1350,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetAudioStreamInputChannelMap(SDL_AudioStre
* Channel maps are optional; most things do not need them, instead passing
* data in the [order that SDL expects](CategoryAudio#channel-layouts).
*
* The output channel map reorders data that leaving a stream via
* 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
@@ -1417,6 +1432,136 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetAudioStreamOutputChannelMap(SDL_AudioStr
*/
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.
*
@@ -1586,8 +1731,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_PauseAudioStreamDevice(SDL_AudioStream *str
* previously been paused. Once unpaused, any bound audio streams will begin
* to progress again, and audio can be generated.
*
* Remember, SDL_OpenAudioDeviceStream opens device in a paused state, so this
* function call is required for audio playback to begin on such device.
* 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
@@ -1844,7 +1989,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_DestroyAudioStream(SDL_AudioStream *stream)
* Also unlike other functions, the audio device begins paused. This is to map
* more closely to SDL2-style behavior, since there is no extra step here to
* bind a stream to begin audio flowing. The audio device should be resumed
* with `SDL_ResumeAudioStreamDevice(stream);`
* with SDL_ResumeAudioStreamDevice().
*
* This function works with both playback and recording devices.
*

View File

@@ -261,9 +261,9 @@
*
* On compilers without restrict support, this is defined to nothing.
*
* \since This macro is available since SDL 3.2.0.
* \since This macro is available since SDL 3.4.0.
*/
#define SDL_RESTRICT __restrict__
#define SDL_RESTRICT __restrict
/**
* Check if the compiler supports a given builtin functionality.
@@ -281,9 +281,61 @@
*/
#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)
@@ -379,7 +431,7 @@
#endif /* SDL_INLINE not defined */
#ifndef SDL_FORCE_INLINE
#ifdef _MSC_VER
#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__
@@ -389,7 +441,7 @@
#endif /* SDL_FORCE_INLINE not defined */
#ifndef SDL_NORETURN
#ifdef __GNUC__
#if defined(__GNUC__)
#define SDL_NORETURN __attribute__((noreturn))
#elif defined(_MSC_VER)
#define SDL_NORETURN __declspec(noreturn)
@@ -484,3 +536,18 @@
#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 */

View File

@@ -136,6 +136,20 @@ typedef enum SDL_CameraPosition
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.
@@ -346,8 +360,9 @@ extern SDL_DECLSPEC SDL_Camera * SDLCALL SDL_OpenCamera(SDL_CameraID instance_id
* on others the approval might be implicit and not alert the user at all.
*
* This function can be used to check the status of that approval. It will
* return 0 if still waiting for user response, 1 if the camera is approved
* for use, and -1 if the user denied access.
* 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
@@ -358,8 +373,9 @@ extern SDL_DECLSPEC SDL_Camera * SDLCALL SDL_OpenCamera(SDL_CameraID instance_id
* SDL_CloseCamera() to dispose of it.
*
* \param camera the opened camera device to query.
* \returns -1 if user denied access to the camera, 1 if user approved access,
* 0 if no decision has been made yet.
* \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.
*
@@ -368,7 +384,7 @@ extern SDL_DECLSPEC SDL_Camera * SDLCALL SDL_OpenCamera(SDL_CameraID instance_id
* \sa SDL_OpenCamera
* \sa SDL_CloseCamera
*/
extern SDL_DECLSPEC int SDLCALL SDL_GetCameraPermissionState(SDL_Camera *camera);
extern SDL_DECLSPEC SDL_CameraPermissionState SDLCALL SDL_GetCameraPermissionState(SDL_Camera *camera);
/**
* Get the instance ID of an opened camera.

View File

@@ -198,11 +198,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_HasPrimarySelectionText(void);
* \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 no data to be sent to the
* "receiver". It is up to the receiver to handle this. Essentially
* returning no data is more or less undefined behavior and may cause
* breakage in receiving applications. The returned data will not be
* freed, so it needs to be retained and dealt with internally.
* 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.
*
@@ -211,8 +210,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_HasPrimarySelectionText(void);
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.
* 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.
*
@@ -239,7 +238,8 @@ typedef void (SDLCALL *SDL_ClipboardCleanupCallback)(void *userdata);
* \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 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.

View File

@@ -344,6 +344,27 @@ extern SDL_DECLSPEC int SDLCALL SDL_GetSystemRAM(void);
*/
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
}

View File

@@ -139,10 +139,12 @@ typedef void (SDLCALL *SDL_DialogFileCallback)(void *userdata, const char * cons
* 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 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.

View File

@@ -0,0 +1,227 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
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
* set(CHECK_ELF_DLNOTES_SRC [==[
* #ifndef __ELF__
* ELF DL notes is only supported on ELF platforms
* #endif
* __attribute__ ((used,aligned(4),section(".note.dlopen"))) static const struct {
* struct { int a; int b; int c; } hdr; char name[4]; __attribute__((aligned(4))) char json[24];
* } dlnote = { { 4, 0x407c0c0aU, 16 }, "FDO", "[\\"a\\":{\\"a\\":\\"1\\",\\"b\\":\\"2\\"}]" };
* int main(int argc, char *argv[]) {
* return argc + dlnote.hdr.a;
* }
* ]==])
* check_c_source_compiles("${CHECK_ELF_DLNOTES_SRC}" COMPILER_SUPPORTS_ELFNOTES)
* if(NOT COMPILER_SUPPORTS_ELFNOTES)
* set(SDL_DISABLE_DLOPEN_NOTES TRUE)
* 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 <SDL3/SDL_stdinc.h>
#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_SONAME_ARRAY1(N1) "[\"" N1 "\"]"
#define SDL_SONAME_ARRAY2(N1,N2) "[\"" N1 "\",\"" N2 "\"]"
#define SDL_SONAME_ARRAY3(N1,N2,N3) "[\"" N1 "\",\"" N2 "\",\"" N3 "\"]"
#define SDL_SONAME_ARRAY4(N1,N2,N3,N4) "[\"" N1 "\",\"" N2 "\",\"" N3 "\",\"" N4 "\"]"
#define SDL_SONAME_ARRAY5(N1,N2,N3,N4,N5) "[\"" N1 "\",\"" N2 "\",\"" N3 "\",\"" N4 "\",\"" N5 "\"]"
#define SDL_SONAME_ARRAY6(N1,N2,N3,N4,N5,N6) "[\"" N1 "\",\"" N2 "\",\"" N3 "\",\"" N4 "\",\"" N5 "\",\"" N6 "\"]"
#define SDL_SONAME_ARRAY7(N1,N2,N3,N4,N5,N6,N7) "[\"" N1 "\",\"" N2 "\",\"" N3 "\",\"" N4 "\",\"" N5 "\",\"" N6 "\",\"" N7 "\"]"
#define SDL_SONAME_ARRAY8(N1,N2,N3,N4,N5,N6,N7,N8) "[\"" N1 "\",\"" N2 "\",\"" N3 "\",\"" N4 "\",\"" N5 "\",\"" N6 "\",\"" N7 "\",\"" N8 "\"]"
#define SDL_SONAME_ARRAY_GET(N1,N2,N3,N4,N5,N6,N7,N8,NAME,...) NAME
#define SDL_SONAME_ARRAY(...) \
SDL_SONAME_ARRAY_GET(__VA_ARGS__, \
SDL_SONAME_ARRAY8, \
SDL_SONAME_ARRAY7, \
SDL_SONAME_ARRAY6, \
SDL_SONAME_ARRAY5, \
SDL_SONAME_ARRAY4, \
SDL_SONAME_ARRAY3, \
SDL_SONAME_ARRAY2, \
SDL_SONAME_ARRAY1 \
)(__VA_ARGS__)
/* Create "unique" variable name using __LINE__,
* so creating elf notes on the same line is not supported
*/
#define SDL_ELF_NOTE_JOIN2(A,B) A##B
#define SDL_ELF_NOTE_JOIN(A,B) SDL_ELF_NOTE_JOIN2(A,B)
#define SDL_ELF_NOTE_UNIQUE_NAME SDL_ELF_NOTE_JOIN(s_SDL_dlopen_note_, __LINE__)
/**
* 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"
* );
* ```
*
* 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"
* );
* ```
*
* \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_SONAME_ARRAY(__VA_ARGS__) "}]", \
SDL_ELF_NOTE_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 */
#define SDL_ELF_NOTE_DLOPEN
#else
#define SDL_ELF_NOTE_DLOPEN(...)
#endif
#endif /* SDL_dlopennote_h */

View File

@@ -252,7 +252,7 @@ SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x)
#elif defined(__x86_64__)
SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x)
{
__asm__("xchgb %b0,%h0": "=Q"(x):"0"(x));
__asm__("xchgb %b0,%h0": "=abcd"(x):"0"(x));
return x;
}
#elif (defined(__powerpc__) || defined(__ppc__))

View File

@@ -30,7 +30,7 @@
* coming and going, the system changing in some way, etc.
*
* An app generally takes a moment, perhaps at the start of a new frame, to
* examine any events that have occured since the last time and process or
* 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
@@ -127,15 +127,17 @@ typedef enum SDL_EventType
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_CONTENT_SCALE_CHANGED,
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 */
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 */
@@ -174,6 +176,8 @@ typedef enum SDL_EventType
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 */
@@ -214,10 +218,15 @@ typedef enum SDL_EventType
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 or primary selection changed */
SDL_EVENT_CLIPBOARD_UPDATE = 0x900, /**< The clipboard changed */
/* Drag and drop events */
SDL_EVENT_DROP_FILE = 0x1000, /**< The system requests a file open */
@@ -298,7 +307,7 @@ typedef struct SDL_CommonEvent
*/
typedef struct SDL_DisplayEvent
{
SDL_EventType type; /**< SDL_DISPLAYEVENT_* */
SDL_EventType type; /**< SDL_EVENT_DISPLAY_* */
Uint32 reserved;
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_DisplayID displayID;/**< The associated display */
@@ -704,6 +713,10 @@ typedef struct 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
@@ -781,7 +794,19 @@ typedef struct SDL_TouchFingerEvent
} SDL_TouchFingerEvent;
/**
* Pressure-sensitive pen proximity event structure (event.pmotion.*)
* 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
@@ -793,6 +818,9 @@ typedef struct SDL_TouchFingerEvent
* 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
@@ -967,7 +995,7 @@ typedef struct SDL_QuitEvent
*/
typedef struct SDL_UserEvent
{
Uint32 type; /**< SDL_EVENT_USER through SDL_EVENT_LAST-1, Uint32 because these are not in the SDL_EventType enumeration */
Uint32 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 */
@@ -1017,6 +1045,7 @@ typedef union SDL_Event
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 */
@@ -1043,7 +1072,7 @@ typedef union SDL_Event
} SDL_Event;
/* Make sure we haven't broken binary compatibility */
SDL_COMPILE_TIME_ASSERT(SDL_Event, sizeof(SDL_Event) == sizeof(((SDL_Event *)NULL)->padding));
SDL_COMPILE_TIME_ASSERT(SDL_Event, sizeof(SDL_Event) == sizeof((SDL_static_cast(SDL_Event *, NULL))->padding));
/* Function prototypes */
@@ -1255,6 +1284,13 @@ extern SDL_DECLSPEC void SDLCALL SDL_FlushEvents(Uint32 minType, Uint32 maxType)
* }
* ```
*
* 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.
@@ -1391,7 +1427,10 @@ typedef bool (SDLCALL *SDL_EventFilter)(void *userdata, SDL_Event *event);
* 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!
* 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
@@ -1404,7 +1443,7 @@ typedef bool (SDLCALL *SDL_EventFilter)(void *userdata, SDL_Event *event);
* the event filter, but events pushed onto the queue with SDL_PeepEvents() do
* not.
*
* \param filter an SDL_EventFilter function to call when an event happens.
* \param 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.
@@ -1567,6 +1606,38 @@ extern SDL_DECLSPEC Uint32 SDLCALL SDL_RegisterEvents(int numevents);
*/
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
}

View File

@@ -77,6 +77,9 @@ extern "C" {
* - `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.
@@ -89,6 +92,8 @@ extern "C" {
* 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
@@ -134,6 +139,12 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetBasePath(void);
* - ...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).
*
@@ -144,6 +155,8 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetBasePath(void);
* 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
@@ -216,6 +229,8 @@ typedef enum SDL_Folder
* \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);
@@ -283,6 +298,8 @@ typedef Uint32 SDL_GlobFlags;
* \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);
@@ -346,6 +363,8 @@ typedef SDL_EnumerationResult (SDLCALL *SDL_EnumerateDirectoryCallback)(void *us
* \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);
@@ -360,6 +379,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_EnumerateDirectory(const char *path, SDL_En
* \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);
@@ -367,7 +388,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_RemovePath(const char *path);
/**
* Rename a file or directory.
*
* If the file at `newpath` already exists, it will replaced.
* 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.
@@ -383,6 +404,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_RemovePath(const char *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);
@@ -423,6 +446,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_RenamePath(const char *oldpath, const char
* \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);
@@ -436,6 +463,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_CopyFile(const char *oldpath, const char *n
* \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);
@@ -444,10 +473,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetPathInfo(const char *path, SDL_PathInfo
* 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
* 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 of `/`. Wildcard characters `*` and `?` never match a path
* separator.
*
* `flags` may be set to SDL_GLOB_CASEINSENSITIVE to make the pattern matching
@@ -490,6 +519,8 @@ extern SDL_DECLSPEC char ** SDLCALL SDL_GlobDirectory(const char *path, const ch
* 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);

View File

@@ -118,6 +118,7 @@ typedef enum SDL_GamepadType
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;
@@ -127,8 +128,9 @@ typedef enum SDL_GamepadType
* For controllers that use a diamond pattern for the face buttons, the
* south/east/west/north buttons below correspond to the locations in the
* diamond pattern. For Xbox controllers, this would be A/B/X/Y, for Nintendo
* Switch controllers, this would be B/A/Y/X, for PlayStation controllers this
* would be Cross/Circle/Square/Triangle.
* 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
@@ -163,14 +165,14 @@ typedef enum SDL_GamepadButton
SDL_GAMEPAD_BUTTON_DPAD_LEFT,
SDL_GAMEPAD_BUTTON_DPAD_RIGHT,
SDL_GAMEPAD_BUTTON_MISC1, /**< Additional button (e.g. Xbox Series X share button, PS5 microphone button, Nintendo Switch Pro capture button, Amazon Luna microphone button, Google Stadia capture button) */
SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1, /**< Upper or primary paddle, under your right hand (e.g. Xbox Elite paddle P1) */
SDL_GAMEPAD_BUTTON_LEFT_PADDLE1, /**< Upper or primary paddle, under your left hand (e.g. Xbox Elite paddle P3) */
SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2, /**< Lower or secondary paddle, under your right hand (e.g. Xbox Elite paddle P2) */
SDL_GAMEPAD_BUTTON_LEFT_PADDLE2, /**< Lower or secondary paddle, under your left hand (e.g. Xbox Elite paddle P4) */
SDL_GAMEPAD_BUTTON_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) */
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) */
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) */
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) */
SDL_GAMEPAD_BUTTON_TOUCHPAD, /**< PS4/PS5 touchpad button */
SDL_GAMEPAD_BUTTON_MISC2, /**< Additional button */
SDL_GAMEPAD_BUTTON_MISC3, /**< Additional button */
SDL_GAMEPAD_BUTTON_MISC4, /**< Additional button */
SDL_GAMEPAD_BUTTON_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
@@ -422,6 +424,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_AddGamepadMappingsFromFile(const char *file)
* \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);
@@ -436,6 +440,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReloadGamepadMappings(void);
* 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);
@@ -448,6 +454,8 @@ extern SDL_DECLSPEC char ** SDLCALL SDL_GetGamepadMappings(int *count);
* 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
@@ -465,6 +473,8 @@ extern SDL_DECLSPEC char * SDLCALL SDL_GetGamepadMappingForGUID(SDL_GUID guid);
* 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
@@ -485,6 +495,8 @@ extern SDL_DECLSPEC char * SDLCALL SDL_GetGamepadMapping(SDL_Gamepad *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.
*
* \sa SDL_AddGamepadMapping
@@ -497,6 +509,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetGamepadMapping(SDL_JoystickID instance_i
*
* \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
@@ -512,6 +526,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_HasGamepad(void);
* 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
@@ -526,6 +542,8 @@ extern SDL_DECLSPEC SDL_JoystickID * SDLCALL SDL_GetGamepads(int *count);
* \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
@@ -542,6 +560,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_IsGamepad(SDL_JoystickID 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
@@ -558,6 +578,8 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetGamepadNameForID(SDL_JoystickID
* \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
@@ -573,6 +595,8 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetGamepadPathForID(SDL_JoystickID
* \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
@@ -589,6 +613,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_GetGamepadPlayerIndexForID(SDL_JoystickID in
* \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
@@ -606,6 +632,8 @@ extern SDL_DECLSPEC SDL_GUID SDLCALL SDL_GetGamepadGUIDForID(SDL_JoystickID inst
* \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
@@ -623,6 +651,8 @@ extern SDL_DECLSPEC Uint16 SDLCALL SDL_GetGamepadVendorForID(SDL_JoystickID inst
* \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
@@ -640,6 +670,8 @@ extern SDL_DECLSPEC Uint16 SDLCALL SDL_GetGamepadProductForID(SDL_JoystickID ins
* \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
@@ -655,6 +687,8 @@ extern SDL_DECLSPEC Uint16 SDLCALL SDL_GetGamepadProductVersionForID(SDL_Joystic
* \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
@@ -671,6 +705,8 @@ extern SDL_DECLSPEC SDL_GamepadType SDLCALL SDL_GetGamepadTypeForID(SDL_Joystick
* \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
@@ -688,6 +724,8 @@ extern SDL_DECLSPEC SDL_GamepadType SDLCALL SDL_GetRealGamepadTypeForID(SDL_Joys
* \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
@@ -702,6 +740,8 @@ extern SDL_DECLSPEC char * SDLCALL SDL_GetGamepadMappingForID(SDL_JoystickID ins
* \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
@@ -717,6 +757,8 @@ extern SDL_DECLSPEC SDL_Gamepad * SDLCALL SDL_OpenGamepad(SDL_JoystickID instanc
* \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);
@@ -727,6 +769,8 @@ extern SDL_DECLSPEC SDL_Gamepad * SDLCALL SDL_GetGamepadFromID(SDL_JoystickID in
* \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
@@ -757,6 +801,8 @@ extern SDL_DECLSPEC SDL_Gamepad * SDLCALL SDL_GetGamepadFromPlayerIndex(int play
* \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);
@@ -775,6 +821,8 @@ extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetGamepadProperties(SDL_Gamepa
* \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);
@@ -787,6 +835,8 @@ extern SDL_DECLSPEC SDL_JoystickID SDLCALL SDL_GetGamepadID(SDL_Gamepad *gamepad
* \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
@@ -801,6 +851,8 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetGamepadName(SDL_Gamepad *gamepad
* \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
@@ -814,6 +866,8 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetGamepadPath(SDL_Gamepad *gamepad
* \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
@@ -827,6 +881,8 @@ extern SDL_DECLSPEC SDL_GamepadType SDLCALL SDL_GetGamepadType(SDL_Gamepad *game
* \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
@@ -841,6 +897,8 @@ extern SDL_DECLSPEC SDL_GamepadType SDLCALL SDL_GetRealGamepadType(SDL_Gamepad *
* \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
@@ -856,6 +914,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_GetGamepadPlayerIndex(SDL_Gamepad *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.
*
* \sa SDL_GetGamepadPlayerIndex
@@ -870,6 +930,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetGamepadPlayerIndex(SDL_Gamepad *gamepad,
* \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
@@ -884,6 +946,8 @@ extern SDL_DECLSPEC Uint16 SDLCALL SDL_GetGamepadVendor(SDL_Gamepad *gamepad);
* \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
@@ -898,6 +962,8 @@ extern SDL_DECLSPEC Uint16 SDLCALL SDL_GetGamepadProduct(SDL_Gamepad *gamepad);
* \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
@@ -912,6 +978,8 @@ extern SDL_DECLSPEC Uint16 SDLCALL SDL_GetGamepadProductVersion(SDL_Gamepad *gam
* \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);
@@ -924,6 +992,8 @@ extern SDL_DECLSPEC Uint16 SDLCALL SDL_GetGamepadFirmwareVersion(SDL_Gamepad *ga
* \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);
@@ -937,6 +1007,8 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetGamepadSerial(SDL_Gamepad *gamep
* \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);
@@ -949,6 +1021,8 @@ extern SDL_DECLSPEC Uint64 SDLCALL SDL_GetGamepadSteamHandle(SDL_Gamepad *gamepa
* `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);
@@ -969,6 +1043,8 @@ extern SDL_DECLSPEC SDL_JoystickConnectionState SDLCALL SDL_GetGamepadConnection
* 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);
@@ -981,6 +1057,8 @@ extern SDL_DECLSPEC SDL_PowerState SDLCALL SDL_GetGamepadPowerInfo(SDL_Gamepad *
* \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);
@@ -1001,6 +1079,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GamepadConnected(SDL_Gamepad *gamepad);
* \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);
@@ -1013,6 +1093,8 @@ extern SDL_DECLSPEC SDL_Joystick * SDLCALL SDL_GetGamepadJoystick(SDL_Gamepad *g
*
* \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
@@ -1028,6 +1110,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_SetGamepadEventsEnabled(bool enabled);
*
* \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
@@ -1044,6 +1128,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GamepadEventsEnabled(void);
* 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);
@@ -1055,6 +1141,8 @@ extern SDL_DECLSPEC SDL_GamepadBinding ** SDLCALL SDL_GetGamepadBindings(SDL_Gam
* 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);
@@ -1071,6 +1159,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_UpdateGamepads(void);
* \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
@@ -1085,6 +1175,8 @@ extern SDL_DECLSPEC SDL_GamepadType SDLCALL SDL_GetGamepadTypeFromString(const c
* 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
@@ -1107,6 +1199,8 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetGamepadStringForType(SDL_Gamepad
* \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
@@ -1121,6 +1215,8 @@ extern SDL_DECLSPEC SDL_GamepadAxis SDLCALL SDL_GetGamepadAxisFromString(const c
* 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
@@ -1137,6 +1233,8 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetGamepadStringForAxis(SDL_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
@@ -1156,10 +1254,14 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GamepadHasAxis(SDL_Gamepad *gamepad, SDL_Ga
* 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 (including 0) on success or 0 (also) on failure; call
* SDL_GetError() for more information.
* \returns axis state.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
@@ -1180,6 +1282,8 @@ extern SDL_DECLSPEC Sint16 SDLCALL SDL_GetGamepadAxis(SDL_Gamepad *gamepad, SDL_
* \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
@@ -1194,6 +1298,8 @@ extern SDL_DECLSPEC SDL_GamepadButton SDLCALL SDL_GetGamepadButtonFromString(con
* 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
@@ -1210,6 +1316,8 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetGamepadStringForButton(SDL_Gamep
* \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
@@ -1223,6 +1331,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GamepadHasButton(SDL_Gamepad *gamepad, SDL_
* \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
@@ -1237,6 +1347,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetGamepadButton(SDL_Gamepad *gamepad, SDL_
* \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
@@ -1250,6 +1362,8 @@ extern SDL_DECLSPEC SDL_GamepadButtonLabel SDLCALL SDL_GetGamepadButtonLabelForT
* \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
@@ -1262,6 +1376,8 @@ extern SDL_DECLSPEC SDL_GamepadButtonLabel SDLCALL SDL_GetGamepadButtonLabel(SDL
* \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
@@ -1276,6 +1392,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_GetNumGamepadTouchpads(SDL_Gamepad *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
@@ -1299,6 +1417,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_GetNumGamepadTouchpadFingers(SDL_Gamepad *ga
* \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
@@ -1312,6 +1432,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetGamepadTouchpadFinger(SDL_Gamepad *gamep
* \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
@@ -1329,6 +1451,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GamepadHasSensor(SDL_Gamepad *gamepad, SDL_
* \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
@@ -1343,6 +1467,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetGamepadSensorEnabled(SDL_Gamepad *gamepa
* \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
@@ -1356,6 +1482,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GamepadSensorEnabled(SDL_Gamepad *gamepad,
* \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);
@@ -1373,6 +1501,8 @@ extern SDL_DECLSPEC float SDLCALL SDL_GetGamepadSensorDataRate(SDL_Gamepad *game
* \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);
@@ -1395,6 +1525,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetGamepadSensorData(SDL_Gamepad *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_RumbleGamepad(SDL_Gamepad *gamepad, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);
@@ -1421,6 +1553,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_RumbleGamepad(SDL_Gamepad *gamepad, Uint16
* \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
@@ -1443,6 +1577,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_RumbleGamepadTriggers(SDL_Gamepad *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_SetGamepadLED(SDL_Gamepad *gamepad, Uint8 red, Uint8 green, Uint8 blue);
@@ -1456,6 +1592,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetGamepadLED(SDL_Gamepad *gamepad, Uint8 r
* \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);
@@ -1466,6 +1604,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SendGamepadEffect(SDL_Gamepad *gamepad, con
* \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
@@ -1480,6 +1620,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_CloseGamepad(SDL_Gamepad *gamepad);
* \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
@@ -1493,6 +1635,8 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetGamepadAppleSFSymbolsNameForButt
* \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

View File

@@ -206,14 +206,20 @@
* underlying graphics API. While it's possible that we have done something
* inefficiently, it's very unlikely especially if you are relatively
* inexperienced with GPU rendering. Please see the performance tips above and
* make sure you are following them. Additionally, tools like RenderDoc can be
* very helpful for diagnosing incorrect behavior and performance issues.
* 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:** Supported on Windows, Linux, Nintendo Switch, and certain
* Android devices. Requires Vulkan 1.0 with the following extensions and
* device features:
* ### 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`
@@ -222,13 +228,37 @@
* - `depthClamp`
* - `shaderClipDistance`
* - `drawIndirectFirstInstance`
* - `sampleRateShading`
*
* **D3D12:** Supported on Windows 10 or newer, Xbox One (GDK), and Xbox
* Series X|S (GDK). Requires a GPU that supports DirectX 12 Feature Level 11_0 and
* 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.
*
* **Metal:** Supported on macOS 10.14+ and iOS/tvOS 13.0+. Hardware
* requirements vary by operating system:
* 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)
@@ -236,6 +266,26 @@
* - 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
@@ -301,6 +351,39 @@
* 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_
@@ -1310,6 +1393,17 @@ typedef struct 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**: 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
@@ -1391,7 +1485,7 @@ typedef struct SDL_GPUTextureRegion
*/
typedef struct SDL_GPUBlitRegion
{
SDL_GPUTexture *texture; /**< The texture. */
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. */
@@ -1520,8 +1614,8 @@ typedef struct SDL_GPUSamplerCreateInfo
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. */
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;
@@ -1613,6 +1707,9 @@ typedef struct SDL_GPUStencilOpState
* \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
{
@@ -1623,8 +1720,8 @@ typedef struct SDL_GPUColorTargetBlendState
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. */
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;
@@ -1636,6 +1733,8 @@ typedef struct SDL_GPUColorTargetBlendState
* \since This struct is available since SDL 3.2.0.
*
* \sa SDL_CreateGPUShader
* \sa SDL_GPUShaderFormat
* \sa SDL_GPUShaderStage
*/
typedef struct SDL_GPUShaderCreateInfo
{
@@ -1741,8 +1840,8 @@ typedef struct SDL_GPURasterizerState
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. */
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;
@@ -1759,8 +1858,8 @@ typedef struct SDL_GPUMultisampleState
{
SDL_GPUSampleCount sample_count; /**< The number of samples to be used in rasterization. */
Uint32 sample_mask; /**< Reserved for future use. Must be set to 0. */
bool enable_mask; /**< Reserved for future use. Must be set to false. */
Uint8 padding1;
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;
@@ -1780,9 +1879,9 @@ typedef struct SDL_GPUDepthStencilState
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. */
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;
@@ -1817,7 +1916,7 @@ 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. */
bool has_depth_stencil_target; /**< true specifies that the pipeline uses a depth-stencil target. */
Uint8 padding1;
Uint8 padding2;
Uint8 padding3;
@@ -1912,6 +2011,7 @@ typedef struct SDL_GPUComputePipelineCreateInfo
* \since This struct is available since SDL 3.2.0.
*
* \sa SDL_BeginGPURenderPass
* \sa SDL_FColor
*/
typedef struct SDL_GPUColorTargetInfo
{
@@ -1924,8 +2024,8 @@ typedef struct SDL_GPUColorTargetInfo
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. */
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;
@@ -1970,6 +2070,9 @@ typedef struct SDL_GPUColorTargetInfo
*
* 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
@@ -1982,10 +2085,10 @@ typedef struct SDL_GPUDepthStencilTargetInfo
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 */
bool cycle; /**< true cycles the texture if the texture is bound and any load ops are not LOAD */
Uint8 clear_stencil; /**< The value to clear the stencil component to at the beginning of the render pass. Ignored if SDL_GPU_LOADOP_CLEAR is not used. */
Uint8 padding1;
Uint8 padding2;
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;
/**
@@ -2002,7 +2105,7 @@ typedef struct SDL_GPUBlitInfo {
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. */
bool cycle; /**< true cycles the destination texture if it is already bound. */
Uint8 padding1;
Uint8 padding2;
Uint8 padding3;
@@ -2031,6 +2134,8 @@ typedef struct SDL_GPUBufferBinding
*
* \sa SDL_BindGPUVertexSamplers
* \sa SDL_BindGPUFragmentSamplers
* \sa SDL_GPUTexture
* \sa SDL_GPUSampler
*/
typedef struct SDL_GPUTextureSamplerBinding
{
@@ -2111,6 +2216,13 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GPUSupportsProperties(
/**
* 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.
@@ -2121,6 +2233,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GPUSupportsProperties(
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_CreateGPUDeviceWithProperties
* \sa SDL_GetGPUShaderFormats
* \sa SDL_GetGPUDeviceDriver
* \sa SDL_DestroyGPUDevice
@@ -2140,8 +2253,31 @@ extern SDL_DECLSPEC SDL_GPUDevice * SDLCALL SDL_CreateGPUDevice(
* 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:
*
@@ -2158,10 +2294,32 @@ extern SDL_DECLSPEC SDL_GPUDevice * SDLCALL SDL_CreateGPUDevice(
* - `SDL_PROP_GPU_DEVICE_CREATE_SHADERS_METALLIB_BOOLEAN`: The app is able to
* provide Metal shader libraries if applicable.
*
* With the D3D12 renderer:
* 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.
*
* 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.
*
* \param props the properties to use.
* \returns a GPU context on success or NULL on failure; call SDL_GetError()
@@ -2177,16 +2335,52 @@ extern SDL_DECLSPEC SDL_GPUDevice * SDLCALL SDL_CreateGPUDevice(
extern SDL_DECLSPEC SDL_GPUDevice * SDLCALL SDL_CreateGPUDeviceWithProperties(
SDL_PropertiesID props);
#define SDL_PROP_GPU_DEVICE_CREATE_DEBUGMODE_BOOLEAN "SDL.gpu.device.create.debugmode"
#define SDL_PROP_GPU_DEVICE_CREATE_PREFERLOWPOWER_BOOLEAN "SDL.gpu.device.create.preferlowpower"
#define SDL_PROP_GPU_DEVICE_CREATE_NAME_STRING "SDL.gpu.device.create.name"
#define SDL_PROP_GPU_DEVICE_CREATE_SHADERS_PRIVATE_BOOLEAN "SDL.gpu.device.create.shaders.private"
#define SDL_PROP_GPU_DEVICE_CREATE_SHADERS_SPIRV_BOOLEAN "SDL.gpu.device.create.shaders.spirv"
#define SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXBC_BOOLEAN "SDL.gpu.device.create.shaders.dxbc"
#define SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXIL_BOOLEAN "SDL.gpu.device.create.shaders.dxil"
#define SDL_PROP_GPU_DEVICE_CREATE_SHADERS_MSL_BOOLEAN "SDL.gpu.device.create.shaders.msl"
#define SDL_PROP_GPU_DEVICE_CREATE_SHADERS_METALLIB_BOOLEAN "SDL.gpu.device.create.shaders.metallib"
#define SDL_PROP_GPU_DEVICE_CREATE_D3D12_SEMANTIC_NAME_STRING "SDL.gpu.device.create.d3d12.semantic"
#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_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"
/**
* 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_phyisical_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.
@@ -2250,6 +2444,116 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetGPUDeviceDriver(SDL_GPUDevice *d
*/
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 */
/**
@@ -2440,7 +2744,8 @@ extern SDL_DECLSPEC SDL_GPUShader * SDLCALL SDL_CreateGPUShader(
* 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.
* 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.
@@ -2482,6 +2787,8 @@ extern SDL_DECLSPEC SDL_GPUShader * SDLCALL SDL_CreateGPUShader(
*
* \sa SDL_UploadToGPUTexture
* \sa SDL_DownloadFromGPUTexture
* \sa SDL_BeginGPURenderPass
* \sa SDL_BeginGPUComputePass
* \sa SDL_BindGPUVertexSamplers
* \sa SDL_BindGPUVertexStorageTextures
* \sa SDL_BindGPUFragmentSamplers
@@ -2638,6 +2945,12 @@ extern SDL_DECLSPEC void SDLCALL SDL_SetGPUTextureName(
*
* 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.
*
@@ -2656,6 +2969,11 @@ extern SDL_DECLSPEC void SDLCALL SDL_InsertGPUDebugLabel(
* 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
@@ -2675,6 +2993,11 @@ extern SDL_DECLSPEC void SDLCALL SDL_PushGPUDebugGroup(
/**
* 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.
@@ -2822,6 +3145,9 @@ extern SDL_DECLSPEC SDL_GPUCommandBuffer * SDLCALL SDL_AcquireGPUCommandBuffer(
* 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.
@@ -2892,6 +3218,14 @@ extern SDL_DECLSPEC void SDLCALL SDL_PushGPUComputeUniformData(
* 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.
@@ -3514,6 +3848,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_UnmapGPUTransferBuffer(
* \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);
@@ -3775,7 +4111,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_ReleaseWindowFromGPUDevice(
* supported via SDL_WindowSupportsGPUPresentMode /
* SDL_WindowSupportsGPUSwapchainComposition prior to calling this function.
*
* SDL_GPU_PRESENTMODE_VSYNC with SDL_GPU_SWAPCHAINCOMPOSITION_SDR are always
* SDL_GPU_PRESENTMODE_VSYNC with SDL_GPU_SWAPCHAINCOMPOSITION_SDR is always
* supported.
*
* \param device a GPU context.
@@ -3849,7 +4185,9 @@ extern SDL_DECLSPEC SDL_GPUTextureFormat SDLCALL SDL_GetGPUSwapchainTextureForma
* 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.
* 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
@@ -4171,6 +4509,29 @@ extern SDL_DECLSPEC Uint32 SDLCALL SDL_CalculateGPUTextureFormatSize(
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
/**

View File

@@ -70,7 +70,7 @@
* {
* SDL_Haptic *haptic;
* SDL_HapticEffect effect;
* int effect_id;
* SDL_HapticEffectID effect_id;
*
* // Open the device
* haptic = SDL_OpenHapticFromJoystick(joystick);
@@ -149,6 +149,19 @@ extern "C" {
*/
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
@@ -162,6 +175,11 @@ typedef struct SDL_Haptic SDL_Haptic;
*/
/* @{ */
/**
* Type of haptic effect.
*/
typedef Uint16 SDL_HapticEffectType;
/**
* Constant effect supported.
*
@@ -383,6 +401,11 @@ typedef struct SDL_Haptic SDL_Haptic;
*/
/* @{ */
/**
* Type of coordinates used for haptic direction.
*/
typedef Uint8 SDL_HapticDirectionType;
/**
* Uses polar coordinates for the direction.
*
@@ -426,18 +449,15 @@ typedef struct SDL_Haptic SDL_Haptic;
/* @} *//* Haptic features */
/*
* Misc defines.
*/
/**
* Used to play a device an infinite number of times.
* ID for haptic effects.
*
* \since This macro is available since SDL 3.2.0.
* This is -1 if the ID is invalid.
*
* \sa SDL_RunHapticEffect
* \sa SDL_CreateHapticEffect
*/
#define SDL_HAPTIC_INFINITY 4294967295U
typedef int SDL_HapticEffectID;
/**
@@ -545,8 +565,8 @@ typedef struct SDL_Haptic SDL_Haptic;
*/
typedef struct SDL_HapticDirection
{
Uint8 type; /**< The type of encoding. */
Sint32 dir[3]; /**< The encoded direction. */
SDL_HapticDirectionType type; /**< The type of encoding. */
Sint32 dir[3]; /**< The encoded direction. */
} SDL_HapticDirection;
@@ -566,7 +586,7 @@ typedef struct SDL_HapticDirection
typedef struct SDL_HapticConstant
{
/* Header */
Uint16 type; /**< SDL_HAPTIC_CONSTANT */
SDL_HapticEffectType type; /**< SDL_HAPTIC_CONSTANT */
SDL_HapticDirection direction; /**< Direction of the effect. */
/* Replay */
@@ -652,9 +672,9 @@ typedef struct SDL_HapticConstant
typedef struct SDL_HapticPeriodic
{
/* Header */
Uint16 type; /**< SDL_HAPTIC_SINE, SDL_HAPTIC_SQUARE
SDL_HAPTIC_TRIANGLE, SDL_HAPTIC_SAWTOOTHUP or
SDL_HAPTIC_SAWTOOTHDOWN */
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 */
@@ -708,8 +728,8 @@ typedef struct SDL_HapticPeriodic
typedef struct SDL_HapticCondition
{
/* Header */
Uint16 type; /**< SDL_HAPTIC_SPRING, SDL_HAPTIC_DAMPER,
SDL_HAPTIC_INERTIA or SDL_HAPTIC_FRICTION */
SDL_HapticEffectType type; /**< SDL_HAPTIC_SPRING, SDL_HAPTIC_DAMPER,
SDL_HAPTIC_INERTIA or SDL_HAPTIC_FRICTION */
SDL_HapticDirection direction; /**< Direction of the effect. */
/* Replay */
@@ -747,7 +767,7 @@ typedef struct SDL_HapticCondition
typedef struct SDL_HapticRamp
{
/* Header */
Uint16 type; /**< SDL_HAPTIC_RAMP */
SDL_HapticEffectType type; /**< SDL_HAPTIC_RAMP */
SDL_HapticDirection direction; /**< Direction of the effect. */
/* Replay */
@@ -786,7 +806,7 @@ typedef struct SDL_HapticRamp
typedef struct SDL_HapticLeftRight
{
/* Header */
Uint16 type; /**< SDL_HAPTIC_LEFTRIGHT */
SDL_HapticEffectType type; /**< SDL_HAPTIC_LEFTRIGHT */
/* Replay */
Uint32 length; /**< Duration of the effect in milliseconds. */
@@ -816,7 +836,7 @@ typedef struct SDL_HapticLeftRight
typedef struct SDL_HapticCustom
{
/* Header */
Uint16 type; /**< SDL_HAPTIC_CUSTOM */
SDL_HapticEffectType type; /**< SDL_HAPTIC_CUSTOM */
SDL_HapticDirection direction; /**< Direction of the effect. */
/* Replay */
@@ -915,7 +935,7 @@ typedef struct SDL_HapticCustom
typedef union SDL_HapticEffect
{
/* Common for all force feedback effects */
Uint16 type; /**< Effect type. */
SDL_HapticEffectType type; /**< Effect type. */
SDL_HapticConstant constant; /**< Constant effect. */
SDL_HapticPeriodic periodic; /**< Periodic effect. */
SDL_HapticCondition condition; /**< Condition effect. */
@@ -1193,7 +1213,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_HapticEffectSupported(SDL_Haptic *haptic, c
* \sa SDL_RunHapticEffect
* \sa SDL_UpdateHapticEffect
*/
extern SDL_DECLSPEC int SDLCALL SDL_CreateHapticEffect(SDL_Haptic *haptic, const SDL_HapticEffect *effect);
extern SDL_DECLSPEC SDL_HapticEffectID SDLCALL SDL_CreateHapticEffect(SDL_Haptic *haptic, const SDL_HapticEffect *effect);
/**
* Update the properties of an effect.
@@ -1215,7 +1235,7 @@ extern SDL_DECLSPEC int SDLCALL SDL_CreateHapticEffect(SDL_Haptic *haptic, const
* \sa SDL_CreateHapticEffect
* \sa SDL_RunHapticEffect
*/
extern SDL_DECLSPEC bool SDLCALL SDL_UpdateHapticEffect(SDL_Haptic *haptic, int effect, const SDL_HapticEffect *data);
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.
@@ -1239,7 +1259,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_UpdateHapticEffect(SDL_Haptic *haptic, int
* \sa SDL_StopHapticEffect
* \sa SDL_StopHapticEffects
*/
extern SDL_DECLSPEC bool SDLCALL SDL_RunHapticEffect(SDL_Haptic *haptic, int effect, Uint32 iterations);
extern SDL_DECLSPEC bool SDLCALL SDL_RunHapticEffect(SDL_Haptic *haptic, SDL_HapticEffectID effect, Uint32 iterations);
/**
* Stop the haptic effect on its associated haptic device.
@@ -1254,7 +1274,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_RunHapticEffect(SDL_Haptic *haptic, int eff
* \sa SDL_RunHapticEffect
* \sa SDL_StopHapticEffects
*/
extern SDL_DECLSPEC bool SDLCALL SDL_StopHapticEffect(SDL_Haptic *haptic, int effect);
extern SDL_DECLSPEC bool SDLCALL SDL_StopHapticEffect(SDL_Haptic *haptic, SDL_HapticEffectID effect);
/**
* Destroy a haptic effect on the device.
@@ -1269,7 +1289,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_StopHapticEffect(SDL_Haptic *haptic, int ef
*
* \sa SDL_CreateHapticEffect
*/
extern SDL_DECLSPEC void SDLCALL SDL_DestroyHapticEffect(SDL_Haptic *haptic, int effect);
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.
@@ -1285,7 +1305,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_DestroyHapticEffect(SDL_Haptic *haptic, int
*
* \sa SDL_GetHapticFeatures
*/
extern SDL_DECLSPEC bool SDLCALL SDL_GetHapticEffectStatus(SDL_Haptic *haptic, int effect);
extern SDL_DECLSPEC bool SDLCALL SDL_GetHapticEffectStatus(SDL_Haptic *haptic, SDL_HapticEffectID effect);
/**
* Set the global gain of the specified haptic device.

View File

@@ -55,6 +55,7 @@
#include <SDL3/SDL_stdinc.h>
#include <SDL3/SDL_error.h>
#include <SDL3/SDL_properties.h>
#include <SDL3/SDL_begin_code.h>
/* Set up for C function definitions, even when using C++ */
@@ -283,6 +284,24 @@ extern SDL_DECLSPEC SDL_hid_device * SDLCALL SDL_hid_open(unsigned short vendor_
*/
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.
*

View File

@@ -391,12 +391,46 @@ extern "C" {
* 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
*
* 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.
*
@@ -685,6 +719,21 @@ extern "C" {
*/
#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.
@@ -711,8 +760,6 @@ extern "C" {
*
* This hint only applies to the emscripten platform.
*
* The default value is "#canvas"
*
* This hint should be set before creating a window.
*
* \since This hint is available since SDL 3.2.0.
@@ -726,7 +773,7 @@ extern "C" {
*
* The variable can be one of:
*
* - "#window": the javascript window object (default)
* - "#window": the javascript window object
* - "#document": the javascript document object
* - "#screen": the javascript window.screen object
* - "#canvas": the WebGL canvas element
@@ -740,6 +787,32 @@ extern "C" {
*/
#define SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT "SDL_EMSCRIPTEN_KEYBOARD_ELEMENT"
/**
* Dictate that windows on Emscripten will fill the whole browser window.
*
* When enabled, the canvas element fills the entire document. Resize events
* will be generated as the browser window is resized, as that will adjust the
* canvas size as well. The canvas will cover anything else on the page,
* including any controls provided by Emscripten in its generated HTML file
* (in fact, any elements on the page that aren't the canvas will be moved
* into a hidden `div` element).
*
* Often times this is desirable for a browser-based game, but it means
* several things that we expect of an SDL window on other platforms might not
* work as expected, such as minimum window sizes and aspect ratios.
*
* This hint overrides SDL_PROP_WINDOW_CREATE_EMSCRIPTEN_FILL_DOCUMENT_BOOLEAN
* properties when creating an SDL window.
*
* This hint only applies to the Emscripten platform.
*
* This hint can be set at any time (before creating the window, or to toggle
* its state later). Only one window can fill the document at a time.
*
* \since This hint is available since SDL 3.4.0.
*/
#define SDL_HINT_EMSCRIPTEN_FILL_DOCUMENT "SDL_EMSCRIPTEN_FILL_DOCUMENT"
/**
* A variable that controls whether the on-screen keyboard should be shown
* when text input is active.
@@ -1143,8 +1216,8 @@ extern "C" {
#define SDL_HINT_IME_IMPLEMENTED_UI "SDL_IME_IMPLEMENTED_UI"
/**
* A variable controlling whether the home indicator bar on iPhone X should be
* hidden.
* 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:
*
@@ -1723,6 +1796,69 @@ extern "C" {
*/
#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.
*
* This variable can be set to the following values:
*
* - "0": HIDAPI driver is not used
* - "1": HIDAPI driver is used
*
* The default is the value of SDL_HINT_JOYSTICK_HIDAPI
*/
#define SDL_HINT_JOYSTICK_HIDAPI_LG4FF "SDL_JOYSTICK_HIDAPI_LG4FF"
/**
* A variable controlling whether the HIDAPI driver for 8BitDo controllers
* should be used.
*
* This variable can be set to the following values:
*
* "0" - HIDAPI driver is not used. "1" - HIDAPI driver is used.
*
* The default is the value of SDL_HINT_JOYSTICK_HIDAPI
*/
#define SDL_HINT_JOYSTICK_HIDAPI_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
*
* This variable can be set to the following values:
*
* "0" - HIDAPI driver is not used. "1" - HIDAPI driver is used.
*
* The default is the value of SDL_HINT_JOYSTICK_HIDAPI
*/
#define SDL_HINT_JOYSTICK_HIDAPI_SINPUT "SDL_JOYSTICK_HIDAPI_SINPUT"
/**
* A variable controlling whether the HIDAPI driver for ZUIKI controllers
* should be used.
*
* This variable can be set to the following values:
*
* "0" - HIDAPI driver is not used. "1" - HIDAPI driver is used.
*
* The default is the value of SDL_HINT_JOYSTICK_HIDAPI
*/
#define SDL_HINT_JOYSTICK_HIDAPI_ZUIKI "SDL_JOYSTICK_HIDAPI_ZUIKI"
/**
* A variable controlling whether the HIDAPI driver for Flydigi controllers
* should be used.
*
* This variable can be set to the following values:
*
* "0" - HIDAPI driver is not used. "1" - HIDAPI driver is used.
*
* The default is the value of SDL_HINT_JOYSTICK_HIDAPI
*/
#define SDL_HINT_JOYSTICK_HIDAPI_FLYDIGI "SDL_JOYSTICK_HIDAPI_FLYDIGI"
/**
* A variable controlling whether the HIDAPI driver for Nintendo Switch
* controllers should be used.
@@ -1774,6 +1910,23 @@ extern "C" {
*/
#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.
@@ -1926,6 +2079,41 @@ extern "C" {
*/
#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 not reset.
*
* 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.
@@ -2228,9 +2416,9 @@ extern "C" {
* pressing the 1 key would yield the keycode SDLK_1, or '1', instead of
* SDLK_AMPERSAND, or '&'
* - "latin_letters": For keyboards using non-Latin letters, such as Russian
* or Thai, the letter keys generate keycodes as though it had an en_US
* layout. e.g. pressing the key associated with SDL_SCANCODE_A on a Russian
* keyboard would yield 'a' instead of a Cyrillic letter.
* 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"
*
@@ -2289,6 +2477,27 @@ extern "C" {
*/
#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.
*
@@ -2309,6 +2518,11 @@ extern "C" {
*
* `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.
@@ -2410,6 +2624,21 @@ extern "C" {
*/
#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 open the accents menu for that key.
* - "1": Holding a key will repeat the pressed 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.
*
@@ -2430,6 +2659,10 @@ extern "C" {
* 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.
@@ -2493,7 +2726,7 @@ extern "C" {
* the window center occur within a short time period, SDL will emulate mouse
* warps using relative mouse mode. This can provide smoother and more
* reliable mouse motion for some older games, which continuously calculate
* the distance travelled by the mouse pointer and warp it back to the center
* 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
@@ -2859,6 +3092,24 @@ extern "C" {
*/
#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.
*
@@ -3041,6 +3292,37 @@ extern "C" {
*/
#define SDL_HINT_ROG_GAMEPAD_MICE_EXCLUDED "SDL_ROG_GAMEPAD_MICE_EXCLUDED"
/**
* Variable controlling the width of the PS2's framebuffer in pixels
*
* By default, this variable is "640"
*/
#define SDL_HINT_PS2_GS_WIDTH "SDL_PS2_GS_WIDTH"
/**
* Variable controlling the height of the PS2's framebuffer in pixels
*
* By default, this variable is "448"
*/
#define SDL_HINT_PS2_GS_HEIGHT "SDL_PS2_GS_HEIGHT"
/**
* Variable controlling whether the signal is interlaced or progressive
*
* - "0": Image is interlaced. (default)
* - "1": Image is progressive
*/
#define SDL_HINT_PS2_GS_PROGRESSIVE "SDL_PS2_GS_PROGRESSIVE"
/**
* Variable controlling the video mode of the console
*
* - "": Console-native. (default)
* - "NTSC": 60hz region
* - "PAL": 50hz region
*/
#define SDL_HINT_PS2_GS_MODE "SDL_PS2_GS_MODE"
/**
* A variable controlling which Dispmanx layer to use on a Raspberry PI.
*
@@ -3407,6 +3689,43 @@ extern "C" {
*/
#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.
@@ -4061,15 +4380,14 @@ extern "C" {
*
* The variable can be set to the following values:
*
* - "0": GameInput is not used for raw keyboard and mouse events.
* - "0": GameInput is not used for raw keyboard and mouse events. (default)
* - "1": GameInput is used for raw keyboard and mouse events, if available.
* (default)
*
* This hint should be set before SDL is initialized.
*
* \since This hint is available since SDL 3.2.0.
*/
#define SDL_HINT_WINDOWS_GAMEINPUT "SDL_WINDOWS_GAMEINPUT"
#define SDL_HINT_WINDOWS_GAMEINPUT "SDL_WINDOWS_GAMEINPUT"
/**
* A variable controlling whether raw keyboard events are used on Windows.
@@ -4085,6 +4403,28 @@ extern "C" {
*/
#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 SDL uses Kernel Semaphores on Windows.
*
@@ -4114,7 +4454,7 @@ extern "C" {
*
* \since This hint is available since SDL 3.2.0.
*/
#define SDL_HINT_WINDOWS_INTRESOURCE_ICON "SDL_WINDOWS_INTRESOURCE_ICON"
#define SDL_HINT_WINDOWS_INTRESOURCE_ICON "SDL_WINDOWS_INTRESOURCE_ICON"
/**
* A variable to specify custom icon resource id from RC file on Windows
@@ -4287,7 +4627,6 @@ extern "C" {
*/
#define SDL_HINT_PEN_TOUCH_EVENTS "SDL_PEN_TOUCH_EVENTS"
/**
* An enumeration of hint priorities.
*
@@ -4386,19 +4725,14 @@ extern SDL_DECLSPEC void SDLCALL SDL_ResetHints(void);
* \param name the hint to query.
* \returns the string value of a hint or NULL if the hint isn't set.
*
* \threadsafety It is safe to call this function from any thread, however the
* return value only remains valid until the hint is changed; if
* another thread might do so, the app should supply locks
* and/or make a copy of the string. Note that using a hint
* callback instead is always thread-safe, as SDL holds a lock
* on the thread subsystem during the callback.
* \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);
extern SDL_DECLSPEC const char *SDLCALL SDL_GetHint(const char *name);
/**
* Get the boolean value of a hint variable.
@@ -4474,8 +4808,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_AddHintCallback(const char *name, SDL_HintC
* \sa SDL_AddHintCallback
*/
extern SDL_DECLSPEC void SDLCALL SDL_RemoveHintCallback(const char *name,
SDL_HintCallback callback,
void *userdata);
SDL_HintCallback callback,
void *userdata);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus

View File

@@ -101,7 +101,7 @@ typedef Uint32 SDL_InitFlags;
* to run.
*
* See
* [Main callbacks in SDL3](https://wiki.libsdl.org/SDL3/README/main-functions#main-callbacks-in-sdl3)
* [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.

View File

@@ -268,6 +268,7 @@ _m_prefetch(void *__P)
#endif /* compiler version */
#ifdef SDL_WIKI_DOCUMENTATION_SECTION
/**
* A macro to decide if the compiler supports `__attribute__((target))`.
*
@@ -280,12 +281,14 @@ _m_prefetch(void *__P)
* \sa SDL_TARGETING
*/
#define SDL_HAS_TARGET_ATTRIBS
#elif defined(__loongarch64) && defined(__GNUC__) && (__GNUC__ >= 15)
/* LoongArch requires GCC 15+ for target attribute support */
# define SDL_HAS_TARGET_ATTRIBS
#elif defined(__clang__) && defined(__has_attribute)
# if __has_attribute(target)
# define SDL_HAS_TARGET_ATTRIBS
# endif
#elif defined(__GNUC__) && (__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) /* gcc >= 4.9 */
#elif defined(__GNUC__) && !defined(__loongarch64) && (__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) /* gcc >= 4.9 */
# define SDL_HAS_TARGET_ATTRIBS
#elif defined(__ICC) && __ICC >= 1600
# define SDL_HAS_TARGET_ATTRIBS

View File

@@ -111,7 +111,7 @@ typedef struct SDL_IOStreamInterface
/**
* Read up to `size` bytes from the data stream to the area pointed
* at by `ptr`.
* at by `ptr`. `size` will always be > 0.
*
* On an incomplete read, you should set `*status` to a value from the
* SDL_IOStatus enum. You do not have to explicitly set this on
@@ -123,7 +123,7 @@ typedef struct SDL_IOStreamInterface
/**
* Write exactly `size` bytes from the area pointed at by `ptr`
* to data stream.
* to data stream. `size` will always be > 0.
*
* On an incomplete write, you should set `*status` to a value from the
* SDL_IOStatus enum. You do not have to explicitly set this on
@@ -203,6 +203,8 @@ typedef struct SDL_IOStream SDL_IOStream;
* - "w": Create an empty file for writing. If a file with the same name
* already exists its content is erased and the file is treated as a new
* empty file.
* - "wx": Create an empty file for writing. If a file with the same name
* already exists, the call fails.
* - "a": Append to a file. Writing operations append data at the end of the
* file. The file is created if it does not exist.
* - "r+": Open a file for update both reading and writing. The file must
@@ -210,6 +212,8 @@ typedef struct SDL_IOStream SDL_IOStream;
* - "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.
* - "w+x": Create an empty file for both reading and writing. If a file with
* the same name already exists, the call fails.
* - "a+": Open a file for reading and appending. All writing operations are
* performed at the end of the file, protecting the previous content to be
* overwritten. You can reposition (fseek, rewind) the internal pointer to
@@ -260,7 +264,7 @@ typedef struct SDL_IOStream SDL_IOStream;
* \returns a pointer to the SDL_IOStream structure that is created or NULL on
* failure; call SDL_GetError() for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
@@ -286,8 +290,7 @@ extern SDL_DECLSPEC SDL_IOStream * SDLCALL SDL_IOFromFile(const char *file, cons
* certain size, for both read and write access.
*
* This memory buffer is not copied by the SDL_IOStream; the pointer you
* provide must remain valid until you close the stream. Closing the stream
* will not free the original buffer.
* provide must remain valid until you close the stream.
*
* If you need to make sure the SDL_IOStream never writes to the memory
* buffer, you should use SDL_IOFromConstMem() with a read-only buffer of
@@ -300,6 +303,13 @@ extern SDL_DECLSPEC SDL_IOStream * SDLCALL SDL_IOFromFile(const char *file, cons
* - `SDL_PROP_IOSTREAM_MEMORY_SIZE_NUMBER`: this will be the `size` parameter
* that was passed to this function.
*
* Additionally, the following properties are recognized:
*
* - `SDL_PROP_IOSTREAM_MEMORY_FREE_FUNC_POINTER`: if this property is set to
* a non-NULL value it will be interpreted as a function of SDL_free_func
* type and called with the passed `mem` pointer when closing the stream. By
* default it is unset, i.e., the memory will not be freed.
*
* \param mem a pointer to a buffer to feed an SDL_IOStream stream.
* \param size the buffer size, in bytes.
* \returns a pointer to a new SDL_IOStream structure or NULL on failure; call
@@ -321,6 +331,7 @@ extern SDL_DECLSPEC SDL_IOStream * SDLCALL SDL_IOFromMem(void *mem, size_t size)
#define SDL_PROP_IOSTREAM_MEMORY_POINTER "SDL.iostream.memory.base"
#define SDL_PROP_IOSTREAM_MEMORY_SIZE_NUMBER "SDL.iostream.memory.size"
#define SDL_PROP_IOSTREAM_MEMORY_FREE_FUNC_POINTER "SDL.iostream.memory.free"
/**
* Use this function to prepare a read-only memory buffer for use with
@@ -333,8 +344,7 @@ extern SDL_DECLSPEC SDL_IOStream * SDLCALL SDL_IOFromMem(void *mem, size_t size)
* without writing to the memory buffer.
*
* This memory buffer is not copied by the SDL_IOStream; the pointer you
* provide must remain valid until you close the stream. Closing the stream
* will not free the original buffer.
* provide must remain valid until you close the stream.
*
* If you need to write to a memory buffer, you should use SDL_IOFromMem()
* with a writable buffer of memory instead.
@@ -346,6 +356,13 @@ extern SDL_DECLSPEC SDL_IOStream * SDLCALL SDL_IOFromMem(void *mem, size_t size)
* - `SDL_PROP_IOSTREAM_MEMORY_SIZE_NUMBER`: this will be the `size` parameter
* that was passed to this function.
*
* Additionally, the following properties are recognized:
*
* - `SDL_PROP_IOSTREAM_MEMORY_FREE_FUNC_POINTER`: if this property is set to
* a non-NULL value it will be interpreted as a function of SDL_free_func
* type and called with the passed `mem` pointer when closing the stream. By
* default it is unset, i.e., the memory will not be freed.
*
* \param mem a pointer to a read-only buffer to feed an SDL_IOStream stream.
* \param size the buffer size, in bytes.
* \returns a pointer to a new SDL_IOStream structure or NULL on failure; call
@@ -452,7 +469,7 @@ extern SDL_DECLSPEC SDL_IOStream * SDLCALL SDL_OpenIO(const SDL_IOStreamInterfac
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*
@@ -467,7 +484,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_CloseIO(SDL_IOStream *context);
* \returns a valid property ID on success or 0 on failure; call
* SDL_GetError() for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -487,7 +504,7 @@ extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetIOProperties(SDL_IOStream *c
* \param context the SDL_IOStream to query.
* \returns an SDL_IOStatus enum with the current state.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -501,7 +518,7 @@ extern SDL_DECLSPEC SDL_IOStatus SDLCALL SDL_GetIOStatus(SDL_IOStream *context);
* negative error code on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -528,7 +545,7 @@ extern SDL_DECLSPEC Sint64 SDLCALL SDL_GetIOSize(SDL_IOStream *context);
* \returns the final offset in the data stream after the seek or -1 on
* failure; call SDL_GetError() for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*
@@ -548,7 +565,7 @@ extern SDL_DECLSPEC Sint64 SDLCALL SDL_SeekIO(SDL_IOStream *context, Sint64 offs
* \returns the current offset in the stream, or -1 if the information can not
* be determined.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*
@@ -567,13 +584,17 @@ extern SDL_DECLSPEC Sint64 SDLCALL SDL_TellIO(SDL_IOStream *context);
* the stream is not at EOF, SDL_GetIOStatus() will return a different error
* value and SDL_GetError() will offer a human-readable message.
*
* A request for zero bytes on a valid stream will return zero immediately
* without accessing the stream, so the stream status (EOF, err, etc) will not
* change.
*
* \param context a pointer to an SDL_IOStream structure.
* \param ptr a pointer to a buffer to read data into.
* \param size the number of bytes to read from the data source.
* \returns the number of bytes read, or 0 on end of file or other failure;
* call SDL_GetError() for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*
@@ -596,13 +617,17 @@ extern SDL_DECLSPEC size_t SDLCALL SDL_ReadIO(SDL_IOStream *context, void *ptr,
* recoverable, such as a non-blocking write that can simply be retried later,
* or a fatal error.
*
* A request for zero bytes on a valid stream will return zero immediately
* without accessing the stream, so the stream status (EOF, err, etc) will not
* change.
*
* \param context a pointer to an SDL_IOStream structure.
* \param ptr a pointer to a buffer containing data to write.
* \param size the number of bytes to write.
* \returns the number of bytes written, which will be less than `size` on
* failure; call SDL_GetError() for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*
@@ -626,7 +651,7 @@ extern SDL_DECLSPEC size_t SDLCALL SDL_WriteIO(SDL_IOStream *context, const void
* \returns the number of bytes written or 0 on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*
@@ -646,7 +671,7 @@ extern SDL_DECLSPEC size_t SDLCALL SDL_IOprintf(SDL_IOStream *context, SDL_PRINT
* \returns the number of bytes written or 0 on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*
@@ -666,7 +691,7 @@ extern SDL_DECLSPEC size_t SDLCALL SDL_IOvprintf(SDL_IOStream *context, SDL_PRIN
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*
@@ -692,7 +717,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_FlushIO(SDL_IOStream *context);
* \returns the data or NULL on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*
@@ -715,7 +740,7 @@ extern SDL_DECLSPEC void * SDLCALL SDL_LoadFile_IO(SDL_IOStream *src, size_t *da
* \returns the data or NULL on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
@@ -736,7 +761,7 @@ extern SDL_DECLSPEC void * SDLCALL SDL_LoadFile(const char *file, size_t *datasi
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*
@@ -755,7 +780,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SaveFile_IO(SDL_IOStream *src, const void *
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
@@ -784,7 +809,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SaveFile(const char *file, const void *data
* \returns true on success or false on failure or EOF; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -803,7 +828,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadU8(SDL_IOStream *src, Uint8 *value);
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -823,10 +848,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadS8(SDL_IOStream *src, Sint8 *value);
*
* \param src the stream from which to read data.
* \param value a pointer filled in with the data read.
* \returns true on successful write or false on failure; call SDL_GetError()
* \returns true on successful read or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -846,10 +871,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadU16LE(SDL_IOStream *src, Uint16 *value)
*
* \param src the stream from which to read data.
* \param value a pointer filled in with the data read.
* \returns true on successful write or false on failure; call SDL_GetError()
* \returns true on successful read or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -869,10 +894,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadS16LE(SDL_IOStream *src, Sint16 *value)
*
* \param src the stream from which to read data.
* \param value a pointer filled in with the data read.
* \returns true on successful write or false on failure; call SDL_GetError()
* \returns true on successful read or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -892,10 +917,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadU16BE(SDL_IOStream *src, Uint16 *value)
*
* \param src the stream from which to read data.
* \param value a pointer filled in with the data read.
* \returns true on successful write or false on failure; call SDL_GetError()
* \returns true on successful read or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -915,10 +940,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadS16BE(SDL_IOStream *src, Sint16 *value)
*
* \param src the stream from which to read data.
* \param value a pointer filled in with the data read.
* \returns true on successful write or false on failure; call SDL_GetError()
* \returns true on successful read or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -938,10 +963,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadU32LE(SDL_IOStream *src, Uint32 *value)
*
* \param src the stream from which to read data.
* \param value a pointer filled in with the data read.
* \returns true on successful write or false on failure; call SDL_GetError()
* \returns true on successful read or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -961,10 +986,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadS32LE(SDL_IOStream *src, Sint32 *value)
*
* \param src the stream from which to read data.
* \param value a pointer filled in with the data read.
* \returns true on successful write or false on failure; call SDL_GetError()
* \returns true on successful read or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -984,10 +1009,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadU32BE(SDL_IOStream *src, Uint32 *value)
*
* \param src the stream from which to read data.
* \param value a pointer filled in with the data read.
* \returns true on successful write or false on failure; call SDL_GetError()
* \returns true on successful read or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -1007,10 +1032,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadS32BE(SDL_IOStream *src, Sint32 *value)
*
* \param src the stream from which to read data.
* \param value a pointer filled in with the data read.
* \returns true on successful write or false on failure; call SDL_GetError()
* \returns true on successful read or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -1030,10 +1055,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadU64LE(SDL_IOStream *src, Uint64 *value)
*
* \param src the stream from which to read data.
* \param value a pointer filled in with the data read.
* \returns true on successful write or false on failure; call SDL_GetError()
* \returns true on successful read or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -1053,10 +1078,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadS64LE(SDL_IOStream *src, Sint64 *value)
*
* \param src the stream from which to read data.
* \param value a pointer filled in with the data read.
* \returns true on successful write or false on failure; call SDL_GetError()
* \returns true on successful read or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -1076,10 +1101,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadU64BE(SDL_IOStream *src, Uint64 *value)
*
* \param src the stream from which to read data.
* \param value a pointer filled in with the data read.
* \returns true on successful write or false on failure; call SDL_GetError()
* \returns true on successful read or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -1101,7 +1126,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_ReadS64BE(SDL_IOStream *src, Sint64 *value)
* \returns true on successful write or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -1115,7 +1140,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_WriteU8(SDL_IOStream *dst, Uint8 value);
* \returns true on successful write or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -1134,7 +1159,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_WriteS8(SDL_IOStream *dst, Sint8 value);
* \returns true on successful write or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -1153,7 +1178,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_WriteU16LE(SDL_IOStream *dst, Uint16 value)
* \returns true on successful write or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -1171,7 +1196,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_WriteS16LE(SDL_IOStream *dst, Sint16 value)
* \returns true on successful write or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -1189,7 +1214,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_WriteU16BE(SDL_IOStream *dst, Uint16 value)
* \returns true on successful write or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -1208,7 +1233,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_WriteS16BE(SDL_IOStream *dst, Sint16 value)
* \returns true on successful write or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -1227,7 +1252,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_WriteU32LE(SDL_IOStream *dst, Uint32 value)
* \returns true on successful write or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -1245,7 +1270,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_WriteS32LE(SDL_IOStream *dst, Sint32 value)
* \returns true on successful write or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -1263,7 +1288,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_WriteU32BE(SDL_IOStream *dst, Uint32 value)
* \returns true on successful write or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -1282,7 +1307,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_WriteS32BE(SDL_IOStream *dst, Sint32 value)
* \returns true on successful write or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -1301,7 +1326,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_WriteU64LE(SDL_IOStream *dst, Uint64 value)
* \returns true on successful write or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -1319,7 +1344,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_WriteS64LE(SDL_IOStream *dst, Sint64 value)
* \returns true on successful write or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/
@@ -1337,7 +1362,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_WriteU64BE(SDL_IOStream *dst, Uint64 value)
* \returns true on successful write or false on failure; call SDL_GetError()
* for more information.
*
* \threadsafety This function is not thread safe.
* \threadsafety Do not use the same SDL_IOStream from two threads at once.
*
* \since This function is available since SDL 3.2.0.
*/

View File

@@ -29,8 +29,8 @@
* instead.
*
* The term "instance_id" is the current instantiation of a joystick device in
* the system, if the joystick is removed and then re-inserted then it will
* get a new instance_id, instance_id's are monotonically increasing
* the system. If the joystick is removed and then re-inserted then it will
* get a new instance_id. instance_id's are monotonically increasing
* identifiers of a joystick plugged in.
*
* The term "player_index" is the number assigned to a player on a specific
@@ -48,6 +48,14 @@
* If you would like to receive joystick updates while the application is in
* the background, you should set the following hint before calling
* SDL_Init(): SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS
*
* SDL can provide virtual joysticks as well: the app defines an imaginary
* controller with SDL_AttachVirtualJoystick(), and then can provide inputs
* for it via SDL_SetJoystickVirtualAxis(), SDL_SetJoystickVirtualButton(),
* etc. As this data is supplied, it will look like a normal joystick to SDL,
* just not backed by a hardware driver. This has been used to make unusual
* devices, like VR headset controllers, look like normal joysticks, or
* provide recording/playback of game inputs, etc.
*/
#ifndef SDL_joystick_h_
@@ -107,6 +115,10 @@ typedef Uint32 SDL_JoystickID;
* This is by no means a complete list of everything that can be plugged into
* a computer.
*
* You may refer to
* [XInput Controller Types](https://learn.microsoft.com/en-us/windows/win32/xinput/xinput-and-controller-subtypes)
* table for a general understanding of each joystick type.
*
* \since This enum is available since SDL 3.2.0.
*/
typedef enum SDL_JoystickType
@@ -170,6 +182,8 @@ typedef enum SDL_JoystickConnectionState
* joysticks while processing to guarantee that the joystick list won't change
* and joystick and gamepad events will not be delivered.
*
* \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_LockJoysticks(void) SDL_ACQUIRE(SDL_joystick_lock);
@@ -177,6 +191,9 @@ extern SDL_DECLSPEC void SDLCALL SDL_LockJoysticks(void) SDL_ACQUIRE(SDL_joystic
/**
* Unlocking for atomic access to the joystick API.
*
* \threadsafety This should be called from the same thread that called
* SDL_LockJoysticks().
*
* \since This function is available since SDL 3.2.0.
*/
extern SDL_DECLSPEC void SDLCALL SDL_UnlockJoysticks(void) SDL_RELEASE(SDL_joystick_lock);
@@ -186,6 +203,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_UnlockJoysticks(void) SDL_RELEASE(SDL_joyst
*
* \returns true if a joystick 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_GetJoysticks
@@ -201,6 +220,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_HasJoystick(void);
* 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_HasJoystick
@@ -217,6 +238,8 @@ extern SDL_DECLSPEC SDL_JoystickID * SDLCALL SDL_GetJoysticks(int *count);
* \returns the name of the selected joystick. 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_GetJoystickName
@@ -233,6 +256,8 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetJoystickNameForID(SDL_JoystickID
* \returns the path of the selected joystick. 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_GetJoystickPath
@@ -248,6 +273,8 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetJoystickPathForID(SDL_JoystickID
* \param instance_id the joystick instance ID.
* \returns the player index of a joystick, 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_GetJoystickPlayerIndex
@@ -264,6 +291,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_GetJoystickPlayerIndexForID(SDL_JoystickID i
* \returns the GUID of the selected joystick. If called with an invalid
* instance_id, 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_GetJoystickGUID
@@ -281,6 +310,8 @@ extern SDL_DECLSPEC SDL_GUID SDLCALL SDL_GetJoystickGUIDForID(SDL_JoystickID ins
* \returns the USB vendor ID of the selected joystick. If called with an
* invalid instance_id, this function returns 0.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetJoystickVendor
@@ -298,6 +329,8 @@ extern SDL_DECLSPEC Uint16 SDLCALL SDL_GetJoystickVendorForID(SDL_JoystickID ins
* \returns the USB product ID of the selected joystick. If called with an
* invalid instance_id, this function returns 0.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetJoystickProduct
@@ -315,6 +348,8 @@ extern SDL_DECLSPEC Uint16 SDLCALL SDL_GetJoystickProductForID(SDL_JoystickID in
* \returns the product version of the selected joystick. If called with an
* invalid instance_id, this function returns 0.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetJoystickProductVersion
@@ -332,6 +367,8 @@ extern SDL_DECLSPEC Uint16 SDLCALL SDL_GetJoystickProductVersionForID(SDL_Joysti
* invalid instance_id, this function returns
* `SDL_JOYSTICK_TYPE_UNKNOWN`.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetJoystickType
@@ -349,6 +386,8 @@ extern SDL_DECLSPEC SDL_JoystickType SDLCALL SDL_GetJoystickTypeForID(SDL_Joysti
* \returns a joystick identifier 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_CloseJoystick
@@ -362,6 +401,8 @@ extern SDL_DECLSPEC SDL_Joystick * SDLCALL SDL_OpenJoystick(SDL_JoystickID insta
* \returns an SDL_Joystick 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_Joystick * SDLCALL SDL_GetJoystickFromID(SDL_JoystickID instance_id);
@@ -373,6 +414,8 @@ extern SDL_DECLSPEC SDL_Joystick * SDLCALL SDL_GetJoystickFromID(SDL_JoystickID
* \returns an SDL_Joystick 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_GetJoystickPlayerIndex
@@ -465,13 +508,33 @@ SDL_COMPILE_TIME_ASSERT(SDL_VirtualJoystickDesc_SIZE,
/**
* Attach a new virtual joystick.
*
* Apps can create virtual joysticks, that exist without hardware directly
* backing them, and have program-supplied inputs. Once attached, a virtual
* joystick looks like any other joystick that SDL can access. These can be
* used to make other things look like joysticks, or provide pre-recorded
* input, etc.
*
* Once attached, the app can send joystick inputs to the new virtual joystick
* using SDL_SetJoystickVirtualAxis(), etc.
*
* When no longer needed, the virtual joystick can be removed by calling
* SDL_DetachVirtualJoystick().
*
* \param desc joystick description, initialized using SDL_INIT_INTERFACE().
* \returns the joystick instance ID, 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_DetachVirtualJoystick
* \sa SDL_SetJoystickVirtualAxis
* \sa SDL_SetJoystickVirtualButton
* \sa SDL_SetJoystickVirtualBall
* \sa SDL_SetJoystickVirtualHat
* \sa SDL_SetJoystickVirtualTouchpad
* \sa SDL_SetJoystickVirtualSensorData
*/
extern SDL_DECLSPEC SDL_JoystickID SDLCALL SDL_AttachVirtualJoystick(const SDL_VirtualJoystickDesc *desc);
@@ -483,6 +546,8 @@ extern SDL_DECLSPEC SDL_JoystickID SDLCALL SDL_AttachVirtualJoystick(const SDL_V
* \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_AttachVirtualJoystick
@@ -495,6 +560,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_DetachVirtualJoystick(SDL_JoystickID instan
* \param instance_id the joystick instance ID.
* \returns true if the joystick is virtual, false otherwise.
*
* \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_IsJoystickVirtual(SDL_JoystickID instance_id);
@@ -518,7 +585,15 @@ extern SDL_DECLSPEC bool SDLCALL SDL_IsJoystickVirtual(SDL_JoystickID instance_i
* \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_SetJoystickVirtualButton
* \sa SDL_SetJoystickVirtualBall
* \sa SDL_SetJoystickVirtualHat
* \sa SDL_SetJoystickVirtualTouchpad
* \sa SDL_SetJoystickVirtualSensorData
*/
extern SDL_DECLSPEC bool SDLCALL SDL_SetJoystickVirtualAxis(SDL_Joystick *joystick, int axis, Sint16 value);
@@ -538,7 +613,15 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetJoystickVirtualAxis(SDL_Joystick *joysti
* \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_SetJoystickVirtualAxis
* \sa SDL_SetJoystickVirtualButton
* \sa SDL_SetJoystickVirtualHat
* \sa SDL_SetJoystickVirtualTouchpad
* \sa SDL_SetJoystickVirtualSensorData
*/
extern SDL_DECLSPEC bool SDLCALL SDL_SetJoystickVirtualBall(SDL_Joystick *joystick, int ball, Sint16 xrel, Sint16 yrel);
@@ -557,7 +640,15 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetJoystickVirtualBall(SDL_Joystick *joysti
* \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_SetJoystickVirtualAxis
* \sa SDL_SetJoystickVirtualBall
* \sa SDL_SetJoystickVirtualHat
* \sa SDL_SetJoystickVirtualTouchpad
* \sa SDL_SetJoystickVirtualSensorData
*/
extern SDL_DECLSPEC bool SDLCALL SDL_SetJoystickVirtualButton(SDL_Joystick *joystick, int button, bool down);
@@ -576,7 +667,15 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetJoystickVirtualButton(SDL_Joystick *joys
* \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_SetJoystickVirtualAxis
* \sa SDL_SetJoystickVirtualButton
* \sa SDL_SetJoystickVirtualBall
* \sa SDL_SetJoystickVirtualTouchpad
* \sa SDL_SetJoystickVirtualSensorData
*/
extern SDL_DECLSPEC bool SDLCALL SDL_SetJoystickVirtualHat(SDL_Joystick *joystick, int hat, Uint8 value);
@@ -602,7 +701,15 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetJoystickVirtualHat(SDL_Joystick *joystic
* \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_SetJoystickVirtualAxis
* \sa SDL_SetJoystickVirtualButton
* \sa SDL_SetJoystickVirtualBall
* \sa SDL_SetJoystickVirtualHat
* \sa SDL_SetJoystickVirtualSensorData
*/
extern SDL_DECLSPEC bool SDLCALL SDL_SetJoystickVirtualTouchpad(SDL_Joystick *joystick, int touchpad, int finger, bool down, float x, float y, float pressure);
@@ -624,7 +731,15 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetJoystickVirtualTouchpad(SDL_Joystick *jo
* \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_SetJoystickVirtualAxis
* \sa SDL_SetJoystickVirtualButton
* \sa SDL_SetJoystickVirtualBall
* \sa SDL_SetJoystickVirtualHat
* \sa SDL_SetJoystickVirtualTouchpad
*/
extern SDL_DECLSPEC bool SDLCALL SDL_SendJoystickVirtualSensorData(SDL_Joystick *joystick, SDL_SensorType type, Uint64 sensor_timestamp, const float *data, int num_values);
@@ -648,6 +763,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SendJoystickVirtualSensorData(SDL_Joystick
* \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_GetJoystickProperties(SDL_Joystick *joystick);
@@ -665,6 +782,8 @@ extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetJoystickProperties(SDL_Joyst
* \returns the name of the selected joystick. 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_GetJoystickNameForID
@@ -678,6 +797,8 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetJoystickName(SDL_Joystick *joyst
* \returns the path of the selected joystick. 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_GetJoystickPathForID
@@ -693,6 +814,8 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetJoystickPath(SDL_Joystick *joyst
* \param joystick the SDL_Joystick obtained from SDL_OpenJoystick().
* \returns the player index, 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_SetJoystickPlayerIndex
@@ -708,6 +831,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_GetJoystickPlayerIndex(SDL_Joystick *joystic
* \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_GetJoystickPlayerIndex
@@ -724,6 +849,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetJoystickPlayerIndex(SDL_Joystick *joysti
* this function returns a zero GUID; 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_GetJoystickGUIDForID
@@ -739,6 +866,8 @@ extern SDL_DECLSPEC SDL_GUID SDLCALL SDL_GetJoystickGUID(SDL_Joystick *joystick)
* \param joystick the SDL_Joystick obtained from SDL_OpenJoystick().
* \returns the USB vendor ID of the selected joystick, 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.
*
* \sa SDL_GetJoystickVendorForID
@@ -753,6 +882,8 @@ extern SDL_DECLSPEC Uint16 SDLCALL SDL_GetJoystickVendor(SDL_Joystick *joystick)
* \param joystick the SDL_Joystick obtained from SDL_OpenJoystick().
* \returns the USB product ID of the selected joystick, 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.
*
* \sa SDL_GetJoystickProductForID
@@ -767,6 +898,8 @@ extern SDL_DECLSPEC Uint16 SDLCALL SDL_GetJoystickProduct(SDL_Joystick *joystick
* \param joystick the SDL_Joystick obtained from SDL_OpenJoystick().
* \returns the product version of the selected joystick, 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.
*
* \sa SDL_GetJoystickProductVersionForID
@@ -782,6 +915,8 @@ extern SDL_DECLSPEC Uint16 SDLCALL SDL_GetJoystickProductVersion(SDL_Joystick *j
* \returns the firmware version of the selected joystick, 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 Uint16 SDLCALL SDL_GetJoystickFirmwareVersion(SDL_Joystick *joystick);
@@ -795,6 +930,8 @@ extern SDL_DECLSPEC Uint16 SDLCALL SDL_GetJoystickFirmwareVersion(SDL_Joystick *
* \returns the serial number of the selected joystick, 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_GetJoystickSerial(SDL_Joystick *joystick);
@@ -805,6 +942,8 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetJoystickSerial(SDL_Joystick *joy
* \param joystick the SDL_Joystick obtained from SDL_OpenJoystick().
* \returns the SDL_JoystickType of the selected joystick.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetJoystickTypeForID
@@ -824,6 +963,8 @@ extern SDL_DECLSPEC SDL_JoystickType SDLCALL SDL_GetJoystickType(SDL_Joystick *j
* \param crc16 a pointer filled in with a CRC used to distinguish different
* products with the same VID/PID, or 0 if 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_GetJoystickGUIDForID
@@ -837,6 +978,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_GetJoystickGUIDInfo(SDL_GUID guid, Uint16 *
* \returns true if the joystick has been opened, false if it has not; 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_JoystickConnected(SDL_Joystick *joystick);
@@ -848,6 +991,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_JoystickConnected(SDL_Joystick *joystick);
* \returns the instance ID of the specified joystick 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_GetJoystickID(SDL_Joystick *joystick);
@@ -863,6 +1008,8 @@ extern SDL_DECLSPEC SDL_JoystickID SDLCALL SDL_GetJoystickID(SDL_Joystick *joyst
* \returns the number of axis controls/number of axes on success 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_GetJoystickAxis
@@ -884,6 +1031,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_GetNumJoystickAxes(SDL_Joystick *joystick);
* \returns the number of trackballs on success 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_GetJoystickBall
@@ -900,6 +1049,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_GetNumJoystickBalls(SDL_Joystick *joystick);
* \returns the number of POV hats on success 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_GetJoystickHat
@@ -916,6 +1067,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_GetNumJoystickHats(SDL_Joystick *joystick);
* \returns the number of buttons on success 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_GetJoystickButton
@@ -934,6 +1087,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_GetNumJoystickButtons(SDL_Joystick *joystick
*
* \param enabled whether to process joystick 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_JoystickEventsEnabled
@@ -950,6 +1105,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_SetJoystickEventsEnabled(bool enabled);
*
* \returns true if joystick 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_SetJoystickEventsEnabled
@@ -962,6 +1119,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_JoystickEventsEnabled(void);
* This is called automatically by the event loop if any joystick events are
* enabled.
*
* \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_UpdateJoysticks(void);
@@ -984,6 +1143,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_UpdateJoysticks(void);
* \returns a 16-bit signed integer representing the current position of the
* axis 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_GetNumJoystickAxes
@@ -1002,6 +1163,8 @@ extern SDL_DECLSPEC Sint16 SDLCALL SDL_GetJoystickAxis(SDL_Joystick *joystick, i
* \param state upon return, the initial value is supplied here.
* \returns true if this axis has any initial value, 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_GetJoystickAxisInitialState(SDL_Joystick *joystick, int axis, Sint16 *state);
@@ -1021,6 +1184,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetJoystickAxisInitialState(SDL_Joystick *j
* \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_GetNumJoystickBalls
@@ -1036,6 +1201,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetJoystickBall(SDL_Joystick *joystick, int
* \param hat the hat index to get the state from; indices start at index 0.
* \returns the current hat position.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GetNumJoystickHats
@@ -1060,6 +1227,8 @@ extern SDL_DECLSPEC Uint8 SDLCALL SDL_GetJoystickHat(SDL_Joystick *joystick, int
* index 0.
* \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_GetNumJoystickButtons
@@ -1083,6 +1252,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetJoystickButton(SDL_Joystick *joystick, i
* \param duration_ms the duration of the rumble effect, in milliseconds.
* \returns true, or false if rumble isn't supported on this joystick.
*
* \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_RumbleJoystick(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);
@@ -1110,6 +1281,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_RumbleJoystick(SDL_Joystick *joystick, Uint
* \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_RumbleJoystick
@@ -1132,6 +1305,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_RumbleJoystickTriggers(SDL_Joystick *joysti
* \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_SetJoystickLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue);
@@ -1145,6 +1320,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetJoystickLED(SDL_Joystick *joystick, Uint
* \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_SendJoystickEffect(SDL_Joystick *joystick, const void *data, int size);
@@ -1154,6 +1331,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SendJoystickEffect(SDL_Joystick *joystick,
*
* \param joystick the joystick device to close.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_OpenJoystick
@@ -1168,6 +1347,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_CloseJoystick(SDL_Joystick *joystick);
* `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_GetJoystickConnectionState(SDL_Joystick *joystick);
@@ -1189,6 +1370,8 @@ extern SDL_DECLSPEC SDL_JoystickConnectionState SDLCALL SDL_GetJoystickConnectio
* \returns the current battery state or `SDL_POWERSTATE_ERROR` 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_PowerState SDLCALL SDL_GetJoystickPowerInfo(SDL_Joystick *joystick, int *percent);

View File

@@ -174,8 +174,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_ResetKeyboard(void);
/**
* Get the current key modifier state for the keyboard.
*
* \returns an OR'd combination of the modifier keys for the keyboard. See
* SDL_Keymod for details.
* \returns an OR'd combination of the modifier keys for the keyboard.
*
* \threadsafety It is safe to call this function from any thread.
*

View File

@@ -45,12 +45,16 @@
* `SDLK_*` constant for those keys that do not generate characters.
*
* A special exception is the number keys at the top of the keyboard which map
* to SDLK_0...SDLK_9 on AZERTY layouts.
* by default to SDLK_0...SDLK_9 on AZERTY layouts.
*
* Keys with the `SDLK_EXTENDED_MASK` bit set do not map to a scancode or
* unicode code point.
*
* Many common keycodes are listed below, but this list is not exhaustive.
*
* \since This datatype is available since SDL 3.2.0.
*
* \sa SDL_HINT_KEYCODE_OPTIONS
*/
typedef Uint32 SDL_Keycode;

View File

@@ -206,6 +206,9 @@ extern SDL_DECLSPEC void SDLCALL SDL_ResetLogPriorities(void);
* SDL_LOG_PRIORITY_WARN and higher have a prefix showing their priority, e.g.
* "WARNING: ".
*
* This function makes a copy of its string argument, **prefix**, so it is not
* necessary to keep the value of **prefix** alive after the call returns.
*
* \param priority the SDL_LogPriority to modify.
* \param prefix the prefix to use for that log priority, or NULL to use no
* prefix.
@@ -263,7 +266,6 @@ extern SDL_DECLSPEC void SDLCALL SDL_Log(SDL_PRINTF_FORMAT_STRING const char *fm
* \sa SDL_LogInfo
* \sa SDL_LogMessage
* \sa SDL_LogMessageV
* \sa SDL_LogTrace
* \sa SDL_LogVerbose
* \sa SDL_LogWarn
*/

View File

@@ -47,7 +47,7 @@
*
* For more information, see:
*
* https://wiki.libsdl.org/SDL3/README/main-functions
* https://wiki.libsdl.org/SDL3/README-main-functions
*/
#ifndef SDL_main_h_
@@ -68,7 +68,7 @@
* proper entry point for the platform, and all the other magic details
* needed, like manually calling SDL_SetMainReady.
*
* Please see [README/main-functions](README/main-functions), (or
* Please see [README-main-functions](README-main-functions), (or
* docs/README-main-functions.md in the source tree) for a more detailed
* explanation.
*
@@ -85,7 +85,7 @@
* SDL_AppQuit. The app should not provide a `main` function in this case, and
* doing so will likely cause the build to fail.
*
* Please see [README/main-functions](README/main-functions), (or
* Please see [README-main-functions](README-main-functions), (or
* docs/README-main-functions.md in the source tree) for a more detailed
* explanation.
*
@@ -110,7 +110,8 @@
* Even if available, an app can define SDL_MAIN_HANDLED and provide their
* own, if they know what they're doing.
*
* This macro is used internally by SDL, and apps probably shouldn't rely on it.
* This macro is used internally by SDL, and apps probably shouldn't rely on
* it.
*
* \since This macro is available since SDL 3.2.0.
*/
@@ -125,10 +126,11 @@
* This macro is defined by `SDL_main.h`, which is not automatically included
* by `SDL.h`.
*
* Even if required, an app can define SDL_MAIN_HANDLED and provide their
* own, if they know what they're doing.
* Even if required, an app can define SDL_MAIN_HANDLED and provide their own,
* if they know what they're doing.
*
* This macro is used internally by SDL, and apps probably shouldn't rely on it.
* This macro is used internally by SDL, and apps probably shouldn't rely on
* it.
*
* \since This macro is available since SDL 3.2.0.
*/
@@ -165,12 +167,10 @@
*/
#define SDL_MAIN_NEEDED
#elif defined(SDL_PLATFORM_IOS)
/* On iOS SDL provides a main function that creates an application delegate
and starts the iOS application run loop.
#elif defined(SDL_PLATFORM_IOS) || defined(SDL_PLATFORM_TVOS)
/* On iOS and tvOS SDL provides a main function that creates an application delegate and starts the application run loop.
To use it, just #include SDL_main.h in the source file that contains your
main() function.
To use it, just #include <SDL3/SDL_main.h> in the source file that contains your main() function.
See src/video/uikit/SDL_uikitappdelegate.m for more details.
*/
@@ -347,10 +347,10 @@ extern SDLMAIN_DECLSPEC SDL_AppResult SDLCALL SDL_AppInit(void **appstate, int a
* Apps implement this function when using SDL_MAIN_USE_CALLBACKS. If using a
* standard "main" function, you should not supply this.
*
* This function is called repeatedly by SDL after SDL_AppInit returns 0. The
* function should operate as a single iteration the program's primary loop;
* it should update whatever state it needs and draw a new frame of video,
* usually.
* This function is called repeatedly by SDL after SDL_AppInit returns
* SDL_APP_CONTINUE. The function should operate as a single iteration the
* program's primary loop; it should update whatever state it needs and draw a
* new frame of video, usually.
*
* On some platforms, this function will be called at the refresh rate of the
* display (which might change during the life of your app!). There are no
@@ -449,8 +449,8 @@ extern SDLMAIN_DECLSPEC SDL_AppResult SDLCALL SDL_AppEvent(void *appstate, SDL_E
*
* This function is called once by SDL before terminating the program.
*
* This function will be called no matter what, even if SDL_AppInit requests
* termination.
* This function will be called in all cases, even if SDL_AppInit requests
* termination at startup.
*
* This function should not go into an infinite mainloop; it should
* deinitialize any resources necessary, perform whatever shutdown activities,
@@ -512,7 +512,7 @@ typedef int (SDLCALL *SDL_main_func)(int argc, char *argv[]);
* SDL_MAIN_USE_CALLBACKS.
*
* Program startup is a surprisingly complex topic. Please see
* [README/main-functions](README/main-functions), (or
* [README-main-functions](README-main-functions), (or
* docs/README-main-functions.md in the source tree) for a more detailed
* explanation.
*
@@ -553,6 +553,9 @@ extern SDL_DECLSPEC void SDLCALL SDL_SetMainReady(void);
* using SDL_main (like when using SDL_MAIN_HANDLED). When using this, you do
* *not* need SDL_SetMainReady().
*
* If `argv` is NULL, SDL will provide command line arguments, either by
* querying the OS for them if possible, or supplying a filler array if not.
*
* \param argc the argc parameter from the application's main() function, or 0
* if the platform's main-equivalent has no argc.
* \param argv the argv parameter from the application's main() function, or
@@ -615,11 +618,12 @@ extern SDL_DECLSPEC int SDLCALL SDL_EnterAppMainCallbacks(int argc, char *argv[]
* Most applications do not need to, and should not, call this directly; SDL
* will call it when initializing the video subsystem.
*
* If `name` is NULL, SDL currently uses `(CS_BYTEALIGNCLIENT | CS_OWNDC)` for
* the style, regardless of what is specified here.
*
* \param name the window class name, in UTF-8 encoding. If NULL, SDL
* currently uses "SDL_app" but this isn't guaranteed.
* \param style the value to use in WNDCLASSEX::style. If `name` is NULL, SDL
* currently uses `(CS_BYTEALIGNCLIENT | CS_OWNDC)` regardless of
* what is specified here.
* \param style the value to use in WNDCLASSEX::style.
* \param hInst the HINSTANCE to use in WNDCLASSEX::hInstance. If zero, SDL
* will use `GetModuleHandle(NULL)` instead.
* \returns true on success or false on failure; call SDL_GetError() for more

View File

@@ -130,6 +130,17 @@ typedef enum SDL_MouseWheelDirection
SDL_MOUSEWHEEL_FLIPPED /**< The scroll direction is flipped / natural */
} SDL_MouseWheelDirection;
/**
* Animated cursor frame info.
*
* \since This struct is available since SDL 3.4.0.
*/
typedef struct SDL_CursorFrameInfo
{
SDL_Surface *surface; /**< The surface data for this frame */
Uint32 duration; /**< The frame duration in milliseconds (a duration of 0 is infinite) */
} SDL_CursorFrameInfo;
/**
* A bitmask of pressed mouse buttons, as reported by SDL_GetMouseState, etc.
*
@@ -160,6 +171,44 @@ typedef Uint32 SDL_MouseButtonFlags;
#define SDL_BUTTON_X1MASK SDL_BUTTON_MASK(SDL_BUTTON_X1)
#define SDL_BUTTON_X2MASK SDL_BUTTON_MASK(SDL_BUTTON_X2)
/**
* A callback used to transform mouse motion delta from raw values.
*
* This is called during SDL's handling of platform mouse events to scale the
* values of the resulting motion delta.
*
* \param userdata what was passed as `userdata` to
* SDL_SetRelativeMouseTransform().
* \param timestamp the associated time at which this mouse motion event was
* received.
* \param window the associated window to which this mouse motion event was
* addressed.
* \param mouseID the associated mouse from which this mouse motion event was
* emitted.
* \param x pointer to a variable that will be treated as the resulting x-axis
* motion.
* \param y pointer to a variable that will be treated as the resulting y-axis
* motion.
*
* \threadsafety This callback is called by SDL's internal mouse input
* processing procedure, which may be a thread separate from the
* main event loop that is run at realtime priority. Stalling
* this thread with too much work in the callback can therefore
* potentially freeze the entire system. Care should be taken
* with proper synchronization practices when adding other side
* effects beyond mutation of the x and y values.
*
* \since This datatype is available since SDL 3.4.0.
*
* \sa SDL_SetRelativeMouseTransform
*/
typedef void (SDLCALL *SDL_MouseMotionTransformCallback)(
void *userdata,
Uint64 timestamp,
SDL_Window *window,
SDL_MouseID mouseID,
float *x, float *y
);
/* Function prototypes */
@@ -380,6 +429,24 @@ extern SDL_DECLSPEC void SDLCALL SDL_WarpMouseInWindow(SDL_Window *window,
*/
extern SDL_DECLSPEC bool SDLCALL SDL_WarpMouseGlobal(float x, float y);
/**
* Set a user-defined function by which to transform relative mouse inputs.
*
* This overrides the relative system scale and relative speed scale hints.
* Should be called prior to enabling relative mouse mode, fails otherwise.
*
* \param callback a callback used to transform relative mouse motion, or NULL
* for default behavior.
* \param userdata a pointer that will be passed to `callback`.
* \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.4.0.
*/
extern SDL_DECLSPEC bool SDLCALL SDL_SetRelativeMouseTransform(SDL_MouseMotionTransformCallback callback, void *userdata);
/**
* Set relative mouse mode for a window.
*
@@ -509,6 +576,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_CaptureMouse(bool enabled);
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_CreateAnimatedCursor
* \sa SDL_CreateColorCursor
* \sa SDL_CreateSystemCursor
* \sa SDL_DestroyCursor
@@ -522,15 +590,16 @@ extern SDL_DECLSPEC SDL_Cursor * SDLCALL SDL_CreateCursor(const Uint8 *data,
/**
* Create a color cursor.
*
* If this function is passed a surface with alternate representations, the
* surface will be interpreted as the content to be used for 100% display
* scale, and the alternate representations will be used for high DPI
* situations. For example, if the original surface is 32x32, then on a 2x
* macOS display or 200% display scale on Windows, a 64x64 version of the
* image will be used, if available. If a matching version of the image isn't
* available, the closest larger size image will be downscaled to the
* appropriate size and be used instead, if available. Otherwise, the closest
* smaller image will be upscaled and be used instead.
* If this function is passed a surface with alternate representations added
* with SDL_AddSurfaceAlternateImage(), the surface will be interpreted as the
* content to be used for 100% display scale, and the alternate
* representations will be used for high DPI situations. For example, if the
* original surface is 32x32, then on a 2x macOS display or 200% display scale
* on Windows, a 64x64 version of the image will be used, if available. If a
* matching version of the image isn't available, the closest larger size
* image will be downscaled to the appropriate size and be used instead, if
* available. Otherwise, the closest smaller image will be upscaled and be
* used instead.
*
* \param surface an SDL_Surface structure representing the cursor image.
* \param hot_x the x position of the cursor hot spot.
@@ -542,6 +611,8 @@ extern SDL_DECLSPEC SDL_Cursor * SDLCALL SDL_CreateCursor(const Uint8 *data,
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_AddSurfaceAlternateImage
* \sa SDL_CreateAnimatedCursor
* \sa SDL_CreateCursor
* \sa SDL_CreateSystemCursor
* \sa SDL_DestroyCursor
@@ -551,6 +622,57 @@ extern SDL_DECLSPEC SDL_Cursor * SDLCALL SDL_CreateColorCursor(SDL_Surface *surf
int hot_x,
int hot_y);
/**
* Create an animated color cursor.
*
* Animated cursors are composed of a sequential array of frames, specified as
* surfaces and durations in an array of SDL_CursorFrameInfo structs. The hot
* spot coordinates are universal to all frames, and all frames must have the
* same dimensions.
*
* Frame durations are specified in milliseconds. A duration of 0 implies an
* infinite frame time, and the animation will stop on that frame. To create a
* one-shot animation, set the duration of the last frame in the sequence to
* 0.
*
* If this function is passed surfaces with alternate representations added
* with SDL_AddSurfaceAlternateImage(), the surfaces will be interpreted as
* the content to be used for 100% display scale, and the alternate
* representations will be used for high DPI situations. For example, if the
* original surfaces are 32x32, then on a 2x macOS display or 200% display
* scale on Windows, a 64x64 version of the image will be used, if available.
* If a matching version of the image isn't available, the closest larger size
* image will be downscaled to the appropriate size and be used instead, if
* available. Otherwise, the closest smaller image will be upscaled and be
* used instead.
*
* If the underlying platform does not support animated cursors, this function
* will fall back to creating a static color cursor using the first frame in
* the sequence.
*
* \param frames an array of cursor images composing the animation.
* \param frame_count the number of frames in the sequence.
* \param hot_x the x position of the cursor hot spot.
* \param hot_y the y position of the cursor hot spot.
* \returns the new cursor on success or NULL 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.4.0.
*
* \sa SDL_AddSurfaceAlternateImage
* \sa SDL_CreateCursor
* \sa SDL_CreateColorCursor
* \sa SDL_CreateSystemCursor
* \sa SDL_DestroyCursor
* \sa SDL_SetCursor
*/
extern SDL_DECLSPEC SDL_Cursor *SDLCALL SDL_CreateAnimatedCursor(SDL_CursorFrameInfo *frames,
int frame_count,
int hot_x,
int hot_y);
/**
* Create a system cursor.
*
@@ -629,6 +751,7 @@ extern SDL_DECLSPEC SDL_Cursor * SDLCALL SDL_GetDefaultCursor(void);
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_CreateAnimatedCursor
* \sa SDL_CreateColorCursor
* \sa SDL_CreateCursor
* \sa SDL_CreateSystemCursor

View File

@@ -360,7 +360,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_LockMutex(SDL_Mutex *mutex) SDL_ACQUIRE(mut
* \sa SDL_LockMutex
* \sa SDL_UnlockMutex
*/
extern SDL_DECLSPEC bool SDLCALL SDL_TryLockMutex(SDL_Mutex *mutex) SDL_TRY_ACQUIRE(0, mutex);
extern SDL_DECLSPEC bool SDLCALL SDL_TryLockMutex(SDL_Mutex *mutex) SDL_TRY_ACQUIRE(true, mutex);
/**
* Unlock the mutex.
@@ -559,7 +559,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_LockRWLockForWriting(SDL_RWLock *rwlock) SD
* \sa SDL_TryLockRWLockForWriting
* \sa SDL_UnlockRWLock
*/
extern SDL_DECLSPEC bool SDLCALL SDL_TryLockRWLockForReading(SDL_RWLock *rwlock) SDL_TRY_ACQUIRE_SHARED(0, rwlock);
extern SDL_DECLSPEC bool SDLCALL SDL_TryLockRWLockForReading(SDL_RWLock *rwlock) SDL_TRY_ACQUIRE_SHARED(true, rwlock);
/**
* Try to lock a read/write lock _for writing_ without blocking.
@@ -589,7 +589,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_TryLockRWLockForReading(SDL_RWLock *rwlock)
* \sa SDL_TryLockRWLockForReading
* \sa SDL_UnlockRWLock
*/
extern SDL_DECLSPEC bool SDLCALL SDL_TryLockRWLockForWriting(SDL_RWLock *rwlock) SDL_TRY_ACQUIRE(0, rwlock);
extern SDL_DECLSPEC bool SDLCALL SDL_TryLockRWLockForWriting(SDL_RWLock *rwlock) SDL_TRY_ACQUIRE(true, rwlock);
/**
* Unlock the read/write lock.
@@ -942,7 +942,7 @@ typedef enum SDL_InitStatus
* Here is an example of using this:
*
* ```c
* static SDL_AtomicInitState init;
* static SDL_InitState init;
*
* bool InitSystem(void)
* {

View File

@@ -28,12 +28,37 @@
* handling, e.g., for input and drawing tablets or suitably equipped mobile /
* tablet devices.
*
* To get started with pens, simply handle SDL_EVENT_PEN_* events. When a pen
* starts providing input, SDL will assign it a unique SDL_PenID, which will
* remain for the life of the process, as long as the pen stays connected.
* To get started with pens, simply handle pen events:
*
* - SDL_EVENT_PEN_PROXIMITY_IN, SDL_EVENT_PEN_PROXIMITY_OUT
* (SDL_PenProximityEvent)
* - SDL_EVENT_PEN_DOWN, SDL_EVENT_PEN_UP (SDL_PenTouchEvent)
* - SDL_EVENT_PEN_MOTION (SDL_PenMotionEvent)
* - SDL_EVENT_PEN_BUTTON_DOWN, SDL_EVENT_PEN_BUTTON_UP (SDL_PenButtonEvent)
* - SDL_EVENT_PEN_AXIS (SDL_PenAxisEvent)
*
* Pens may provide more than simple touch input; they might have other axes,
* such as pressure, tilt, rotation, etc.
*
* When a pen starts providing input, SDL will assign it a unique SDL_PenID,
* which will remain for the life of the process, as long as the pen stays
* connected. A pen leaving proximity (being taken far enough away from the
* digitizer tablet that it no longer reponds) and then coming back should
* fire proximity events, but the SDL_PenID should remain consistent.
* Unplugging the digitizer and reconnecting may cause future input to have a
* new SDL_PenID, as SDL may not know that this is the same hardware.
*
* Please note that various platforms vary wildly in how (and how well) they
* support pen input. If your pen supports some piece of functionality but SDL
* doesn't seem to, it might actually be the operating system's fault. For
* example, some platforms can manage multiple devices at the same time, but
* others will make any connected pens look like a single logical device, much
* how all USB mice connected to a computer will move the same system cursor.
* cursor. Other platforms might not support pen buttons, or the distance
* axis, etc. Very few platforms can even report _what_ functionality the pen
* supports in the first place, so best practices is to either build UI to let
* the user configure their pens, or be prepared to handle new functionality
* for a pen the first time an event is reported.
*/
#ifndef SDL_pen_h_
@@ -43,6 +68,7 @@
#include <SDL3/SDL_mouse.h>
#include <SDL3/SDL_touch.h>
#include <SDL3/SDL_begin_code.h>
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
@@ -55,7 +81,12 @@ extern "C" {
*
* These show up in pen events when SDL sees input from them. They remain
* consistent as long as SDL can recognize a tool to be the same pen; but if a
* pen physically leaves the area and returns, it might get a new ID.
* pen's digitizer table is physically detached from the computer, it might
* get a new ID when reconnected, as SDL won't know it's the same device.
*
* These IDs are only stable within a single run of a program; the next time a
* program is run, the pen's ID will likely be different, even if the hardware
* hasn't been disconnected, etc.
*
* \since This datatype is available since SDL 3.2.0.
*/
@@ -75,7 +106,6 @@ typedef Uint32 SDL_PenID;
*/
#define SDL_PEN_TOUCHID ((SDL_TouchID)-2)
/**
* Pen input flags, as reported by various pen events' `pen_state` field.
*
@@ -83,13 +113,14 @@ typedef Uint32 SDL_PenID;
*/
typedef Uint32 SDL_PenInputFlags;
#define SDL_PEN_INPUT_DOWN (1u << 0) /**< pen is pressed down */
#define SDL_PEN_INPUT_BUTTON_1 (1u << 1) /**< button 1 is pressed */
#define SDL_PEN_INPUT_BUTTON_2 (1u << 2) /**< button 2 is pressed */
#define SDL_PEN_INPUT_BUTTON_3 (1u << 3) /**< button 3 is pressed */
#define SDL_PEN_INPUT_BUTTON_4 (1u << 4) /**< button 4 is pressed */
#define SDL_PEN_INPUT_BUTTON_5 (1u << 5) /**< button 5 is pressed */
#define SDL_PEN_INPUT_ERASER_TIP (1u << 30) /**< eraser tip is used */
#define SDL_PEN_INPUT_DOWN (1u << 0) /**< pen is pressed down */
#define SDL_PEN_INPUT_BUTTON_1 (1u << 1) /**< button 1 is pressed */
#define SDL_PEN_INPUT_BUTTON_2 (1u << 2) /**< button 2 is pressed */
#define SDL_PEN_INPUT_BUTTON_3 (1u << 3) /**< button 3 is pressed */
#define SDL_PEN_INPUT_BUTTON_4 (1u << 4) /**< button 4 is pressed */
#define SDL_PEN_INPUT_BUTTON_5 (1u << 5) /**< button 5 is pressed */
#define SDL_PEN_INPUT_ERASER_TIP (1u << 30) /**< eraser tip is used */
#define SDL_PEN_INPUT_IN_PROXIMITY (1u << 31) /**< pen is in proximity (since SDL 3.4.0) */
/**
* Pen axis indices.
@@ -118,10 +149,50 @@ typedef enum SDL_PenAxis
SDL_PEN_AXIS_COUNT /**< Total known pen axis types in this version of SDL. This number may grow in future releases! */
} SDL_PenAxis;
/**
* An enum that describes the type of a pen device.
*
* A "direct" device is a pen that touches a graphic display (like an Apple
* Pencil on an iPad's screen). "Indirect" devices touch an external tablet
* surface that is connected to the machine but is not a display (like a
* lower-end Wacom tablet connected over USB).
*
* Apps may use this information to decide if they should draw a cursor; if
* the pen is touching the screen directly, a cursor doesn't make sense and
* can be in the way, but becomes necessary for indirect devices to know where
* on the display they are interacting.
*
* \since This enum is available since SDL 3.4.0.
*/
typedef enum SDL_PenDeviceType
{
SDL_PEN_DEVICE_TYPE_INVALID = -1, /**< Not a valid pen device. */
SDL_PEN_DEVICE_TYPE_UNKNOWN, /**< Don't know specifics of this pen. */
SDL_PEN_DEVICE_TYPE_DIRECT, /**< Pen touches display. */
SDL_PEN_DEVICE_TYPE_INDIRECT /**< Pen touches something that isn't the display. */
} SDL_PenDeviceType;
/**
* Get the device type of the given pen.
*
* Many platforms do not supply this information, so an app must always be
* prepared to get an SDL_PEN_DEVICE_TYPE_UNKNOWN result.
*
* \param instance_id the pen instance ID.
* \returns the device type of the given pen, or SDL_PEN_DEVICE_TYPE_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.4.0.
*/
extern SDL_DECLSPEC SDL_PenDeviceType SDLCALL SDL_GetPenDeviceType(SDL_PenID instance_id);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#include <SDL3/SDL_close_code.h>
#endif /* SDL_pen_h_ */

View File

@@ -451,7 +451,7 @@ typedef enum SDL_PackedLayout
* expressions with side-effects here.
*
* \param format an SDL_PixelFormat to check.
* \returns true if the format is 10-bit, false otherwise.
* \returns true if the format is a floating point, false otherwise.
*
* \threadsafety It is safe to call this macro from any thread.
*
@@ -1096,7 +1096,7 @@ typedef enum SDL_Colorspace
SDL_CHROMA_LOCATION_LEFT), */
SDL_COLORSPACE_RGB_DEFAULT = SDL_COLORSPACE_SRGB, /**< The default colorspace for RGB surfaces if no colorspace is specified */
SDL_COLORSPACE_YUV_DEFAULT = SDL_COLORSPACE_JPEG /**< The default colorspace for YUV surfaces if no colorspace is specified */
SDL_COLORSPACE_YUV_DEFAULT = SDL_COLORSPACE_BT601_LIMITED /**< The default colorspace for YUV surfaces if no colorspace is specified */
} SDL_Colorspace;
/**
@@ -1379,7 +1379,7 @@ extern SDL_DECLSPEC Uint32 SDLCALL SDL_MapRGBA(const SDL_PixelFormatDetails *for
* (e.g., a completely white pixel in 16-bit RGB565 format would return [0xff,
* 0xff, 0xff] not [0xf8, 0xfc, 0xf8]).
*
* \param pixel a pixel value.
* \param pixelvalue a pixel value.
* \param format a pointer to SDL_PixelFormatDetails describing the pixel
* format.
* \param palette an optional palette for indexed formats, may be NULL.
@@ -1397,7 +1397,7 @@ extern SDL_DECLSPEC Uint32 SDLCALL SDL_MapRGBA(const SDL_PixelFormatDetails *for
* \sa SDL_MapRGB
* \sa SDL_MapRGBA
*/
extern SDL_DECLSPEC void SDLCALL SDL_GetRGB(Uint32 pixel, const SDL_PixelFormatDetails *format, const SDL_Palette *palette, Uint8 *r, Uint8 *g, Uint8 *b);
extern SDL_DECLSPEC void SDLCALL SDL_GetRGB(Uint32 pixelvalue, const SDL_PixelFormatDetails *format, const SDL_Palette *palette, Uint8 *r, Uint8 *g, Uint8 *b);
/**
* Get RGBA values from a pixel in the specified format.
@@ -1410,7 +1410,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_GetRGB(Uint32 pixel, const SDL_PixelFormatD
* If the surface has no alpha component, the alpha will be returned as 0xff
* (100% opaque).
*
* \param pixel a pixel value.
* \param pixelvalue a pixel value.
* \param format a pointer to SDL_PixelFormatDetails describing the pixel
* format.
* \param palette an optional palette for indexed formats, may be NULL.
@@ -1429,7 +1429,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_GetRGB(Uint32 pixel, const SDL_PixelFormatD
* \sa SDL_MapRGB
* \sa SDL_MapRGBA
*/
extern SDL_DECLSPEC void SDLCALL SDL_GetRGBA(Uint32 pixel, const SDL_PixelFormatDetails *format, const SDL_Palette *palette, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a);
extern SDL_DECLSPEC void SDLCALL SDL_GetRGBA(Uint32 pixelvalue, const SDL_PixelFormatDetails *format, const SDL_Palette *palette, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a);
/* Ends C function definitions when using C++ */

View File

@@ -190,7 +190,7 @@
#if TARGET_OS_VISION
/**
* A preprocessor macro that is only defined if compiling for VisionOS.
* A preprocessor macro that is only defined if compiling for visionOS.
*
* \since This macro is available since SDL 3.2.0.
*
@@ -202,7 +202,7 @@
#if TARGET_OS_IPHONE
/**
* A preprocessor macro that is only defined if compiling for iOS.
* A preprocessor macro that is only defined if compiling for iOS or visionOS.
*
* \since This macro is available since SDL 3.2.0.
*
@@ -317,7 +317,7 @@
#define SDL_PLATFORM_CYGWIN 1
#endif
#if defined(_WIN32) || defined(SDL_PLATFORM_CYGWIN)
#if (defined(_WIN32) || defined(SDL_PLATFORM_CYGWIN)) && !defined(__NGAGE__)
/**
* A preprocessor macro that is only defined if compiling for Windows.
@@ -473,4 +473,25 @@
#define SDL_PLATFORM_3DS 1
#endif
#ifdef __NGAGE__
/**
* A preprocessor macro that is only defined if compiling for the Nokia
* N-Gage.
*
* \since This macro is available since SDL 3.4.0.
*/
#define SDL_PLATFORM_NGAGE 1
#endif
#ifdef __GNU__
/**
* A preprocessor macro that is only defined if compiling for GNU/Hurd.
*
* \since This macro is available since SDL 3.4.0.
*/
#define SDL_PLATFORM_HURD 1
#endif
#endif /* SDL_platform_defines_h_ */

View File

@@ -88,8 +88,8 @@ typedef enum SDL_PowerState
* can't determine a value or there is no battery.
* \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.
* filled in with -1 when we can't determine a value or there
* is no battery.
* \returns the current battery state or `SDL_POWERSTATE_ERROR` on failure;
* call SDL_GetError() for more information.
*

View File

@@ -166,6 +166,9 @@ typedef enum SDL_ProcessIO
* - `SDL_PROP_PROCESS_CREATE_ENVIRONMENT_POINTER`: an SDL_Environment
* pointer. If this property is set, it will be the entire environment for
* the process, otherwise the current environment is used.
* - `SDL_PROP_PROCESS_CREATE_WORKING_DIRECTORY_STRING`: a UTF-8 encoded
* string representing the working directory for the process, defaults to
* the current working directory.
* - `SDL_PROP_PROCESS_CREATE_STDIN_NUMBER`: an SDL_ProcessIO value describing
* where standard input for the process comes from, defaults to
* `SDL_PROCESS_STDIO_NULL`.
@@ -192,6 +195,12 @@ typedef enum SDL_ProcessIO
* run in the background. In this case the default input and output is
* `SDL_PROCESS_STDIO_NULL` and the exitcode of the process is not
* available, and will always be 0.
* - `SDL_PROP_PROCESS_CREATE_CMDLINE_STRING`: a string containing the program
* to run and any parameters. This string is passed directly to
* `CreateProcess` on Windows, and does nothing on other platforms. This
* property is only important if you want to start programs that does
* non-standard command-line processing, and in most cases using
* `SDL_PROP_PROCESS_CREATE_ARGS_POINTER` is sufficient.
*
* On POSIX platforms, wait() and waitpid(-1, ...) should not be called, and
* SIGCHLD should not be ignored or handled because those would prevent SDL
@@ -219,6 +228,7 @@ extern SDL_DECLSPEC SDL_Process * SDLCALL SDL_CreateProcessWithProperties(SDL_Pr
#define SDL_PROP_PROCESS_CREATE_ARGS_POINTER "SDL.process.create.args"
#define SDL_PROP_PROCESS_CREATE_ENVIRONMENT_POINTER "SDL.process.create.environment"
#define SDL_PROP_PROCESS_CREATE_WORKING_DIRECTORY_STRING "SDL.process.create.working_directory"
#define SDL_PROP_PROCESS_CREATE_STDIN_NUMBER "SDL.process.create.stdin_option"
#define SDL_PROP_PROCESS_CREATE_STDIN_POINTER "SDL.process.create.stdin_source"
#define SDL_PROP_PROCESS_CREATE_STDOUT_NUMBER "SDL.process.create.stdout_option"
@@ -227,6 +237,7 @@ extern SDL_DECLSPEC SDL_Process * SDLCALL SDL_CreateProcessWithProperties(SDL_Pr
#define SDL_PROP_PROCESS_CREATE_STDERR_POINTER "SDL.process.create.stderr_source"
#define SDL_PROP_PROCESS_CREATE_STDERR_TO_STDOUT_BOOLEAN "SDL.process.create.stderr_to_stdout"
#define SDL_PROP_PROCESS_CREATE_BACKGROUND_BOOLEAN "SDL.process.create.background"
#define SDL_PROP_PROCESS_CREATE_CMDLINE_STRING "SDL.process.create.cmdline"
/**
* Get the properties associated with a process.

View File

@@ -59,7 +59,7 @@ extern "C" {
#endif
/**
* SDL properties ID
* An ID that represents a properties set.
*
* \since This datatype is available since SDL 3.2.0.
*/
@@ -80,6 +80,31 @@ typedef enum SDL_PropertyType
SDL_PROPERTY_TYPE_BOOLEAN
} SDL_PropertyType;
/**
* A generic property for naming things.
*
* This property is intended to be added to any SDL_PropertiesID that needs a
* generic name associated with the property set. It is not guaranteed that
* any property set will include this key, but it is convenient to have a
* standard key that any piece of code could reasonably agree to use.
*
* For example, the properties associated with an SDL_Texture might have a
* name string of "player sprites", or an SDL_AudioStream might have
* "background music", etc. This might also be useful for an SDL_IOStream to
* list the path to its asset.
*
* There is no format for the value set with this key; it is expected to be
* human-readable and informational in nature, possibly for logging or
* debugging purposes.
*
* SDL does not currently set this property on any objects it creates, but
* this may change in later versions; it is currently expected that apps and
* external libraries will take advantage of it, when appropriate.
*
* \since This macro is available since SDL 3.4.0.
*/
#define SDL_PROP_NAME_STRING "SDL.name"
/**
* Get the global SDL properties.
*
@@ -119,7 +144,9 @@ extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_CreateProperties(void);
* \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.
* \threadsafety It is safe to call this function from any thread. This
* function acquires simultaneous mutex locks on both the source
* and destination property sets.
*
* \since This function is available since SDL 3.2.0.
*/

View File

@@ -88,8 +88,11 @@ typedef struct SDL_Rect
/**
* A rectangle, with the origin at the upper left (using floating point
* values).
* A rectangle stored using floating point values.
*
* The origin of the coordinate space is in the top-left, with increasing
* values moving down and right. The properties `x` and `y` represent the
* coordinates of the top-left corner of the rectangle.
*
* \since This struct is available since SDL 3.2.0.
*
@@ -125,10 +128,10 @@ typedef struct SDL_FRect
*/
SDL_FORCE_INLINE void SDL_RectToFRect(const SDL_Rect *rect, SDL_FRect *frect)
{
frect->x = (float)rect->x;
frect->y = (float)rect->y;
frect->w = (float)rect->w;
frect->h = (float)rect->h;
frect->x = SDL_static_cast(float, rect->x);
frect->y = SDL_static_cast(float, rect->y);
frect->w = SDL_static_cast(float, rect->w);
frect->h = SDL_static_cast(float, rect->h);
}
/**
@@ -324,7 +327,7 @@ SDL_FORCE_INLINE bool SDL_PointInRectFloat(const SDL_FPoint *p, const SDL_FRect
}
/**
* Determine whether a floating point rectangle can contain any point.
* Determine whether a floating point rectangle takes no space.
*
* A rectangle is considered "empty" for this function if `r` is NULL, or if
* `r`'s width and/or height are < 0.0f.

Some files were not shown because too many files have changed in this diff Show More