Merge branch 'libsdl-org:main' into main

This commit is contained in:
Coder2 2025-10-03 10:05:32 +08:00 committed by GitHub
commit e51d3de63a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
411 changed files with 39913 additions and 26123 deletions

View file

@ -20,7 +20,6 @@ class AppleArch(Enum):
class MsvcArch(Enum):
X86 = "x86"
X64 = "x64"
Arm32 = "arm"
Arm64 = "arm64"
@ -31,7 +30,8 @@ class JobOs(Enum):
Ubuntu22_04 = "ubuntu-22.04"
Ubuntu24_04 = "ubuntu-24.04"
Ubuntu24_04_arm = "ubuntu-24.04-arm"
Macos13 = "macos-13"
Macos13 = "macos-13" # macOS Ventura (2022)
Macos26 = "macos-26" # macOS Tahoe (2025)
class SdlPlatform(Enum):
@ -112,7 +112,6 @@ JOB_SPECS = {
"msvc-x86": JobSpec(name="Windows (MSVC, x86)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-x86", msvc_arch=MsvcArch.X86, msvc_project="VisualC/SDL.sln", ),
"msvc-clang-x64": JobSpec(name="Windows (MSVC, clang-cl x64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-clang-cl-x64", msvc_arch=MsvcArch.X64, clang_cl=True, ),
"msvc-clang-x86": JobSpec(name="Windows (MSVC, clang-cl x86)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-clang-cl-x86", msvc_arch=MsvcArch.X86, clang_cl=True, ),
"msvc-arm32": JobSpec(name="Windows (MSVC, ARM)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-arm32", msvc_arch=MsvcArch.Arm32, ),
"msvc-arm64": JobSpec(name="Windows (MSVC, ARM64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-arm64", msvc_arch=MsvcArch.Arm64, ),
"msvc-gdk-x64": JobSpec(name="GDK (MSVC, x64)", os=JobOs.WindowsLatest, platform=SdlPlatform.Msvc, artifact="SDL-VC-GDK", msvc_arch=MsvcArch.X64, msvc_project="VisualC-GDK/SDL.sln", gdk=True, no_cmake=True, ),
"ubuntu-22.04": JobSpec(name="Ubuntu 22.04", os=JobOs.Ubuntu22_04, platform=SdlPlatform.Linux, artifact="SDL-ubuntu22.04", ),
@ -123,6 +122,7 @@ JOB_SPECS = {
"ubuntu-intel-icc": JobSpec(name="Ubuntu 22.04 (Intel Compiler)", os=JobOs.Ubuntu22_04, platform=SdlPlatform.Linux, artifact="SDL-ubuntu22.04-icc", intel=IntelCompiler.Icc, ),
"macos-framework-x64": JobSpec(name="MacOS (Framework) (x64)", os=JobOs.Macos13, platform=SdlPlatform.MacOS, artifact="SDL-macos-framework", apple_framework=True, apple_archs={AppleArch.Aarch64, AppleArch.X86_64, }, xcode=True, ),
"macos-framework-arm64": JobSpec(name="MacOS (Framework) (arm64)", os=JobOs.MacosLatest, platform=SdlPlatform.MacOS, artifact=None, apple_framework=True, apple_archs={AppleArch.Aarch64, AppleArch.X86_64, }, ),
"macos-26-framework-arm64": JobSpec(name="MacOS 26 (Framework) (arm64)",os=JobOs.Macos26, platform=SdlPlatform.MacOS, artifact=None, apple_framework=True, apple_archs={AppleArch.Aarch64, AppleArch.X86_64, }, ),
"macos-gnu-arm64": JobSpec(name="MacOS (GNU prefix)", os=JobOs.MacosLatest, platform=SdlPlatform.MacOS, artifact="SDL-macos-arm64-gnu", apple_framework=False, apple_archs={AppleArch.Aarch64, }, ),
"ios": JobSpec(name="iOS (CMake & xcode)", os=JobOs.MacosLatest, platform=SdlPlatform.Ios, artifact="SDL-ios-arm64", xcode=True, ),
"tvos": JobSpec(name="tvOS (CMake & xcode)", os=JobOs.MacosLatest, platform=SdlPlatform.Tvos, artifact="SDL-tvos-arm64", xcode=True, ),
@ -421,10 +421,6 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
job.msvc_vcvars_arch = "x64_x86"
case MsvcArch.X64:
job.msvc_vcvars_arch = "x64"
case MsvcArch.Arm32:
job.msvc_vcvars_arch = "x64_arm"
job.msvc_vcvars_sdk = "10.0.22621.0" # 10.0.26100.0 dropped ARM32 um and ucrt libraries
job.run_tests = False
case MsvcArch.Arm64:
job.msvc_vcvars_arch = "x64_arm64"
job.run_tests = False
@ -530,11 +526,14 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
job.shared_lib = SharedLibType.DYLIB
job.static_lib = StaticLibType.A
job.ccache = True
if spec.os == JobOs.Macos13:
job.ccache = False
job.apt_packages = []
job.brew_packages.extend((
"ccache",
"ninja",
))
if job.ccache:
job.brew_packages.append("ccache")
if job.clang_tidy:
job.brew_packages.append("llvm")
if spec.xcode:

View file

@ -30,6 +30,7 @@ jobs:
install: >-
${{ matrix.platform.msys2-env }}-cc
${{ matrix.platform.msys2-env }}-cmake
${{ matrix.platform.msys2-env }}-ffmpeg
${{ matrix.platform.msys2-env }}-ninja
${{ (!matrix.platform.msys2-no-perl && format('{0}-perl', matrix.platform.msys2-env)) || '' }}
${{ matrix.platform.msys2-env }}-pkg-config

2
.gitignore vendored
View file

@ -50,6 +50,7 @@ compile_commands.json
*.pc
test/*.test
wayland-generated-protocols
CMakeSettings.json
# for CLion
.idea
@ -98,6 +99,7 @@ src/render/direct3d12/D3D12_*_One.h
src/render/direct3d12/D3D12_*_Series.h
src/gpu/d3d12/D3D12_*_One.h
src/gpu/d3d12/D3D12_*_Series.h
out/
# for Android
android-project/local.properties

View file

@ -123,6 +123,12 @@ include $(BUILD_SHARED_LIBRARY)
#
###########################
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include $(LOCAL_PATH)/src
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_MODULE := SDL3_test
LOCAL_MODULE_FILENAME := libSDL3_test
@ -139,24 +145,4 @@ LOCAL_EXPORT_LDLIBS :=
include $(BUILD_STATIC_LIBRARY)
###########################
#
# SDL static library
#
###########################
LOCAL_MODULE := SDL3_static
LOCAL_MODULE_FILENAME := libSDL3
LOCAL_LDLIBS :=
LOCAL_LDFLAGS :=
LOCAL_EXPORT_LDLIBS := -ldl -lGLESv1_CM -lGLESv2 -llog -landroid
include $(BUILD_STATIC_LIBRARY)
$(call import-module,android/cpufeatures)

View file

@ -382,7 +382,6 @@ set_option(SDL_LIBUDEV "Enable libudev support" ON)
set_option(SDL_ASAN "Use AddressSanitizer to detect memory errors" OFF)
set_option(SDL_CCACHE "Use Ccache to speed up build" OFF)
set_option(SDL_CLANG_TIDY "Run clang-tidy static analysis" OFF)
set_option(SDL_GPU_DXVK "Build SDL_GPU with DXVK support" OFF)
set(SDL_VENDOR_INFO "" CACHE STRING "Vendor name and/or version to add to SDL_REVISION")
@ -457,6 +456,7 @@ if(SDL_SHARED)
add_library(SDL3-shared SHARED)
add_library(SDL3::SDL3-shared ALIAS SDL3-shared)
SDL_AddCommonCompilerFlags(SDL3-shared)
target_compile_definitions(SDL3-shared PRIVATE "$<$<CONFIG:Debug>:DEBUG>")
set_property(TARGET SDL3-shared PROPERTY UNITY_BUILD OFF)
if ("c_std_99" IN_LIST CMAKE_C_COMPILE_FEATURES)
target_compile_features(SDL3-shared PRIVATE c_std_99)
@ -469,6 +469,7 @@ if(SDL_STATIC)
add_library(SDL3-static STATIC)
add_library(SDL3::SDL3-static ALIAS SDL3-static)
SDL_AddCommonCompilerFlags(SDL3-static)
target_compile_definitions(SDL3-static PRIVATE "$<$<CONFIG:Debug>:DEBUG>")
set_property(TARGET SDL3-static PROPERTY UNITY_BUILD OFF)
if ("c_std_99" IN_LIST CMAKE_C_COMPILE_FEATURES)
target_compile_features(SDL3-static PRIVATE c_std_99)
@ -481,6 +482,7 @@ if(SDL_TEST_LIBRARY)
add_library(SDL3_test STATIC)
add_library(SDL3::SDL3_test ALIAS SDL3_test)
SDL_AddCommonCompilerFlags(SDL3_test)
target_compile_definitions(SDL3_test PRIVATE "$<$<CONFIG:Debug>:DEBUG>")
endif()
# Make sure SDL3::SDL3 always exists
@ -638,6 +640,10 @@ if(USE_GCC OR USE_CLANG OR USE_INTELCC OR USE_QCC)
if(COMPILER_SUPPORTS_WNO_ERROR_DEPRECATED_DECLARATIONS)
sdl_compile_options(PRIVATE "-Wno-error=deprecated-declarations")
endif()
check_c_compiler_flag(-Wno-deprecated-declarations COMPILER_SUPPORTS_WNO_DEPRECATED_DECLARATIONS)
if(COMPILER_SUPPORTS_WNO_DEPRECATED_DECLARATIONS)
sdl_compile_options(PRIVATE "-Wno-deprecated-declarations")
endif()
endif()
if(APPLE)
@ -1264,6 +1270,7 @@ target_include_directories(SDL_uclibc PRIVATE "${SDL3_BINARY_DIR}/include-config
target_include_directories(SDL_uclibc PRIVATE "${SDL3_SOURCE_DIR}/src")
target_include_directories(SDL_uclibc PRIVATE "${SDL3_SOURCE_DIR}/include")
SDL_AddCommonCompilerFlags(SDL_uclibc)
target_compile_definitions(SDL_uclibc PRIVATE "$<$<CONFIG:Debug>:DEBUG>")
sdl_sources(STATIC "$<TARGET_OBJECTS:SDL_uclibc>")
set_property(TARGET SDL_uclibc PROPERTY UNITY_BUILD OFF)
if(TARGET SDL3-shared)
@ -1607,6 +1614,9 @@ if(ANDROID)
endif()
endif()
endif()
if(TARGET SDL3-static)
target_link_options(SDL3-static INTERFACE "-Wl,-u,JNI_OnLoad")
endif()
if(TARGET SDL3-shared)
target_link_options(SDL3-shared PRIVATE "-Wl,-z,max-page-size=16384")
@ -2038,16 +2048,6 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
)
endif()
if(SDL_GPU AND SDL_GPU_DXVK)
if(PKG_CONFIG_FOUND)
pkg_search_module(DXVK_NATIVE dxvk-dxgi)
if(DXVK_NATIVE_FOUND)
set(HAVE_D3D11_H TRUE)
sdl_include_directories(PRIVATE SYSTEM ${DXVK_NATIVE_INCLUDE_DIRS})
endif()
endif()
endif()
if(HAVE_LIBURING_H)
sdl_sources("${SDL3_SOURCE_DIR}/src/io/io_uring/SDL_asyncio_liburing.c")
endif()
@ -2221,7 +2221,7 @@ elseif(WINDOWS)
else()
set(PROCESSOR_ARCH "x86")
endif()
sdl_link_directories("$<BUILD_INTERFACE:$$ENV{DXSDK_DIR}\\lib\\${PROCESSOR_ARCH}>")
sdl_link_directories("$<BUILD_INTERFACE:$ENV{DXSDK_DIR}\\lib\\${PROCESSOR_ARCH}>")
sdl_include_directories(PRIVATE SYSTEM "$<BUILD_INTERFACE:$ENV{DXSDK_DIR}\\Include>")
endif()
endif()
@ -2232,7 +2232,8 @@ elseif(WINDOWS)
check_c_source_compiles("
#include <windows.h>
#include <xinput.h>
int main(int argc, char **argv) { return 0; }" HAVE_XINPUT_H)
int main(int argc, char **argv) { return 0; }" HAVE_XINPUT_H
)
endif()
# headers needed elsewhere
@ -2261,6 +2262,7 @@ elseif(WINDOWS)
#include <mfapi.h>
#include <mfidl.h>
#include <mfreadwrite.h>
static MFVideoPrimaries primaries = MFVideoPrimaries_DCI_P3;
int main(int argc, char **argv) { return 0; }
" HAVE_MFAPI_H
)
@ -2304,7 +2306,7 @@ elseif(WINDOWS)
set(SDL_VIDEO_RENDER_D3D11 1)
set(HAVE_RENDER_D3D11 TRUE)
endif()
if(SDL_RENDER_D3D12)
if(SDL_RENDER_D3D12 AND HAVE_DXGI1_6_H)
set(SDL_VIDEO_RENDER_D3D12 1)
set(HAVE_RENDER_D3D12 TRUE)
endif()
@ -2655,6 +2657,7 @@ elseif(APPLE)
set(SDL_FRAMEWORK_UIKIT 1)
set(SDL_IPHONE_KEYBOARD 1)
set(SDL_IPHONE_LAUNCHSCREEN 1)
set(SDL_FRAMEWORK_GAMECONTROLLER 1)
sdl_glob_sources(
"${SDL3_SOURCE_DIR}/src/video/uikit/*.m"
"${SDL3_SOURCE_DIR}/src/video/uikit/*.h"
@ -3438,6 +3441,10 @@ if (SDL_DIALOG)
set(HAVE_SDL_DIALOG TRUE)
endif()
endif()
if(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
sdl_sources(${SDL3_SOURCE_DIR}/src/dialog/unix/SDL_zenitymessagebox.h)
sdl_sources(${SDL3_SOURCE_DIR}/src/dialog/unix/SDL_zenitymessagebox.c)
endif()
sdl_sources("${SDL3_SOURCE_DIR}/src/process/SDL_process.c")
if(WINDOWS)
@ -3511,15 +3518,7 @@ endif()
sdl_glob_sources(${SDL3_SOURCE_DIR}/src/tray/*.c)
if(SDL_GPU)
if(HAVE_D3D11_H)
sdl_glob_sources(
"${SDL3_SOURCE_DIR}/src/gpu/d3d11/*.c"
"${SDL3_SOURCE_DIR}/src/gpu/d3d11/*.h"
)
set(SDL_GPU_D3D11 1)
set(HAVE_SDL_GPU TRUE)
endif()
if(WINDOWS)
if(HAVE_DXGI1_6_H)
sdl_glob_sources(
"${SDL3_SOURCE_DIR}/src/gpu/d3d12/*.c"
"${SDL3_SOURCE_DIR}/src/gpu/d3d12/*.h"
@ -3535,7 +3534,7 @@ if(SDL_GPU)
set(SDL_GPU_VULKAN 1)
set(HAVE_SDL_GPU TRUE)
endif()
if(SDL_RENDER_GPU)
if(SDL_RENDER_GPU AND HAVE_SDL_GPU)
set(SDL_VIDEO_RENDER_GPU 1)
set(HAVE_RENDER_GPU TRUE)
endif()
@ -3691,14 +3690,15 @@ endforeach()
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/REVISION.txt")
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/REVISION.txt" revisions)
list(GET revisions 0 revisions_0)
string(STRIP "${revisions_0}" SDL_REVISION)
string(STRIP "${revisions_0}" revisions_0_stripped)
set(SDL_REVISION "SDL-${revisions_0_stripped}")
else()
set(SDL_REVISION "" CACHE STRING "Custom SDL revision (only used when REVISION.txt does not exist)")
endif()
if(NOT SDL_REVISION)
# If SDL_REVISION is not overrided, use git to describe
git_describe(SDL_REVISION_GIT)
set(SDL_REVISION "SDL3-${SDL3_VERSION}-${SDL_REVISION_GIT}")
set(SDL_REVISION "SDL-${SDL3_VERSION}-${SDL_REVISION_GIT}")
endif()
execute_process(COMMAND "${CMAKE_COMMAND}" -E make_directory "${SDL3_BINARY_DIR}/include-revision/SDL3")

View file

@ -423,6 +423,7 @@
<ClInclude Include="..\..\src\camera\SDL_camera_c.h" />
<ClInclude Include="..\..\src\camera\SDL_syscamera.h" />
<ClInclude Include="..\..\src\core\gdk\SDL_gdk.h" />
<ClInclude Include="..\..\src\core\SDL_core_unsupported.h" />
<ClInclude Include="..\..\src\core\windows\SDL_directx.h" />
<ClInclude Include="..\..\src\core\windows\SDL_gameinput.h" />
<ClInclude Include="..\..\src\core\windows\SDL_hid.h" />
@ -600,6 +601,7 @@
<ClInclude Include="..\..\src\video\SDL_stb_c.h" />
<ClInclude Include="..\..\src\video\SDL_surface_c.h" />
<ClInclude Include="..\..\src\video\SDL_sysvideo.h" />
<ClInclude Include="..\..\src\video\SDL_video_unsupported.h" />
<ClInclude Include="..\..\src\video\SDL_vulkan_internal.h" />
<ClInclude Include="..\..\src\video\SDL_yuv_c.h" />
<ClInclude Include="..\..\src\video\windows\SDL_msctf.h" />
@ -734,6 +736,7 @@
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_xbox360w.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_xboxone.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_lg4ff.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_zuiki.c" />
<ClCompile Include="..\..\src\joystick\SDL_gamepad.c" />
<ClCompile Include="..\..\src\joystick\SDL_joystick.c" />
<ClCompile Include="..\..\src\joystick\SDL_steam_virtual_gamepad.c" />

View file

@ -86,6 +86,7 @@
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_xbox360w.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_xboxone.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_lg4ff.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_zuiki.c" />
<ClCompile Include="..\..\src\joystick\SDL_gamepad.c" />
<ClCompile Include="..\..\src\joystick\SDL_joystick.c" />
<ClCompile Include="..\..\src\joystick\SDL_steam_virtual_gamepad.c" />
@ -330,6 +331,7 @@
<ClInclude Include="..\..\src\core\windows\SDL_immdevice.h" />
<ClInclude Include="..\..\src\core\windows\SDL_windows.h" />
<ClInclude Include="..\..\src\core\windows\SDL_xinput.h" />
<ClInclude Include="..\..\src\core\SDL_core_unsupported.h" />
<ClInclude Include="..\..\src\cpuinfo\SDL_cpuinfo_c.h" />
<ClInclude Include="..\..\src\dynapi\SDL_dynapi.h" />
<ClInclude Include="..\..\src\dynapi\SDL_dynapi_overrides.h" />
@ -452,6 +454,7 @@
<ClInclude Include="..\..\src\video\SDL_stb_c.h" />
<ClInclude Include="..\..\src\video\SDL_surface_c.h" />
<ClInclude Include="..\..\src\video\SDL_sysvideo.h" />
<ClInclude Include="..\..\src\video\SDL_video_unsupported.h" />
<ClInclude Include="..\..\src\video\SDL_vulkan_internal.h" />
<ClInclude Include="..\..\src\video\SDL_yuv_c.h" />
<ClInclude Include="..\..\src\video\windows\SDL_msctf.h" />

View file

@ -334,6 +334,7 @@
<ClInclude Include="..\..\src\audio\wasapi\SDL_wasapi.h" />
<ClInclude Include="..\..\src\camera\SDL_camera_c.h" />
<ClInclude Include="..\..\src\camera\SDL_syscamera.h" />
<ClInclude Include="..\..\src\core\SDL_core_unsupported.h" />
<ClInclude Include="..\..\src\core\windows\SDL_directx.h" />
<ClInclude Include="..\..\src\core\windows\SDL_gameinput.h" />
<ClInclude Include="..\..\src\core\windows\SDL_hid.h" />
@ -508,6 +509,7 @@
<ClInclude Include="..\..\src\video\SDL_stb_c.h" />
<ClInclude Include="..\..\src\video\SDL_surface_c.h" />
<ClInclude Include="..\..\src\video\SDL_sysvideo.h" />
<ClInclude Include="..\..\src\video\SDL_video_unsupported.h" />
<ClInclude Include="..\..\src\video\SDL_vulkan_internal.h" />
<ClInclude Include="..\..\src\video\SDL_yuv_c.h" />
<ClInclude Include="..\..\src\video\windows\SDL_msctf.h" />
@ -624,6 +626,7 @@
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_xbox360w.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_xboxone.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_lg4ff.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_zuiki.c" />
<ClCompile Include="..\..\src\joystick\SDL_gamepad.c" />
<ClCompile Include="..\..\src\joystick\SDL_joystick.c" />
<ClCompile Include="..\..\src\joystick\SDL_steam_virtual_gamepad.c" />

View file

@ -489,6 +489,9 @@
<ClInclude Include="..\..\src\audio\SDL_audioresample.h">
<Filter>audio</Filter>
</ClInclude>
<ClCompile Include="..\..\src\core\SDL_core_unsupported.h">
<Filter>core</Filter>
</ClCompile>
<ClInclude Include="..\..\src\core\windows\SDL_directx.h">
<Filter>core\windows</Filter>
</ClInclude>
@ -684,12 +687,15 @@
<ClInclude Include="..\..\src\video\SDL_stb_c.h">
<Filter>video</Filter>
</ClInclude>
<ClInclude Include="..\..\src\video\SDL_yuv_c.h">
<ClInclude Include="..\..\src\video\SDL_video_unsupported.h">
<Filter>video</Filter>
</ClInclude>
<ClInclude Include="..\..\src\video\SDL_vulkan_internal.h">
<Filter>video</Filter>
</ClInclude>
<ClInclude Include="..\..\src\video\SDL_yuv_c.h">
<Filter>video</Filter>
</ClInclude>
<ClInclude Include="..\..\src\video\dummy\SDL_nullevents_c.h">
<Filter>video\dummy</Filter>
</ClInclude>
@ -1254,6 +1260,9 @@
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_lg4ff.c">
<Filter>joystick\hidapi</Filter>
</ClCompile>
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_zuiki.c">
<Filter>joystick\hidapi</Filter>
</ClCompile>
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapijoystick.c">
<Filter>joystick\hidapi</Filter>
</ClCompile>

View file

@ -66,6 +66,7 @@
566E26D8246274CC00718109 /* SDL_locale.c in Sources */ = {isa = PBXBuildFile; fileRef = 566E26CD246274CB00718109 /* SDL_locale.c */; };
566E26E1246274CC00718109 /* SDL_syslocale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26CE246274CC00718109 /* SDL_syslocale.h */; };
56A2373329F9C113003CCA5F /* SDL_sysrwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 56A2373229F9C113003CCA5F /* SDL_sysrwlock.c */; };
63124A422E5C357500A53610 /* SDL_hidapi_zuiki.c in Sources */ = {isa = PBXBuildFile; fileRef = 63124A412E5C357500A53610 /* SDL_hidapi_zuiki.c */; };
6312C66D2B42341400A7BB00 /* SDL_murmur3.c in Sources */ = {isa = PBXBuildFile; fileRef = 6312C66C2B42341400A7BB00 /* SDL_murmur3.c */; };
63134A252A7902FD0021E9A6 /* SDL_pen_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 63134A232A7902FD0021E9A6 /* SDL_pen_c.h */; };
63134A262A7902FD0021E9A6 /* SDL_pen.c in Sources */ = {isa = PBXBuildFile; fileRef = 63134A242A7902FD0021E9A6 /* SDL_pen.c */; };
@ -614,6 +615,7 @@
566E26CD246274CB00718109 /* SDL_locale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_locale.c; path = locale/SDL_locale.c; sourceTree = "<group>"; };
566E26CE246274CC00718109 /* SDL_syslocale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_syslocale.h; path = locale/SDL_syslocale.h; sourceTree = "<group>"; };
56A2373229F9C113003CCA5F /* SDL_sysrwlock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_sysrwlock.c; sourceTree = "<group>"; };
63124A412E5C357500A53610 /* SDL_hidapi_zuiki.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_zuiki.c; sourceTree = "<group>"; };
6312C66C2B42341400A7BB00 /* SDL_murmur3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_murmur3.c; sourceTree = "<group>"; };
63134A232A7902FD0021E9A6 /* SDL_pen_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_pen_c.h; sourceTree = "<group>"; };
63134A242A7902FD0021E9A6 /* SDL_pen.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_pen.c; sourceTree = "<group>"; };
@ -1964,6 +1966,7 @@
A7D8A7C223E2513E00DCD162 /* SDL_hidapi_xbox360.c */,
A7D8A7C823E2513E00DCD162 /* SDL_hidapi_xbox360w.c */,
A7D8A7C523E2513E00DCD162 /* SDL_hidapi_xboxone.c */,
63124A412E5C357500A53610 /* SDL_hidapi_zuiki.c */,
A7D8A7C423E2513E00DCD162 /* SDL_hidapijoystick.c */,
A7D8A7C723E2513E00DCD162 /* SDL_hidapijoystick_c.h */,
);
@ -3116,6 +3119,7 @@
00004D0B73767647AD550000 /* SDL_asyncio_generic.c in Sources */,
0000A03C0F32C43816F40000 /* SDL_asyncio_windows_ioring.c in Sources */,
0000A877C7DB9FA935FC0000 /* SDL_uikitpen.m in Sources */,
63124A422E5C357500A53610 /* SDL_hidapi_zuiki.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3181,7 +3185,7 @@
SUPPORTED_PLATFORMS = "xrsimulator xros macosx iphonesimulator iphoneos appletvsimulator appletvos";
SUPPORTS_MACCATALYST = YES;
TVOS_DEPLOYMENT_TARGET = 11.0;
XROS_DEPLOYMENT_TARGET = 1.0;
XROS_DEPLOYMENT_TARGET = 1.3;
};
name = Release;
};
@ -3245,7 +3249,7 @@
SUPPORTED_PLATFORMS = "xrsimulator xros macosx iphonesimulator iphoneos appletvsimulator appletvos";
SUPPORTS_MACCATALYST = YES;
TVOS_DEPLOYMENT_TARGET = 11.0;
XROS_DEPLOYMENT_TARGET = 1.0;
XROS_DEPLOYMENT_TARGET = 1.3;
};
name = Debug;
};

View file

@ -162,6 +162,7 @@
F36C34232C0F85DB00991150 /* SDL3.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL3.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
F36C342D2C0F869B00991150 /* testcamera.c in Sources */ = {isa = PBXBuildFile; fileRef = F36C342C2C0F869B00991150 /* testcamera.c */; };
F36C342E2C0F869B00991150 /* testcamera.c in Sources */ = {isa = PBXBuildFile; fileRef = F36C342C2C0F869B00991150 /* testcamera.c */; };
F38908B72E81276900CE01D5 /* testautomation_blit.c in Sources */ = {isa = PBXBuildFile; fileRef = F38908B42E81276900CE01D5 /* testautomation_blit.c */; };
F399C64E2A78929400C86979 /* gamepadutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F399C6492A78929400C86979 /* gamepadutils.c */; };
F399C64F2A78929400C86979 /* gamepadutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F399C6492A78929400C86979 /* gamepadutils.c */; };
F399C6512A7892D800C86979 /* testautomation_intrinsics.c in Sources */ = {isa = PBXBuildFile; fileRef = F399C6502A7892D800C86979 /* testautomation_intrinsics.c */; };
@ -1367,6 +1368,9 @@
F35E56CD2983130F00A43A5F /* testautomation_mouse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testautomation_mouse.c; sourceTree = "<group>"; };
F36C34272C0F85DB00991150 /* testcamera.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testcamera.app; sourceTree = BUILT_PRODUCTS_DIR; };
F36C342C2C0F869B00991150 /* testcamera.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testcamera.c; sourceTree = "<group>"; };
F38908B42E81276900CE01D5 /* testautomation_blit.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = testautomation_blit.c; sourceTree = "<group>"; };
F38908B52E81276900CE01D5 /* testautomation_images.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = testautomation_images.h; sourceTree = "<group>"; };
F38908B62E81276900CE01D5 /* testautomation_suites.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = testautomation_suites.h; sourceTree = "<group>"; };
F399C6492A78929400C86979 /* gamepadutils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gamepadutils.c; sourceTree = "<group>"; };
F399C6502A7892D800C86979 /* testautomation_intrinsics.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testautomation_intrinsics.c; sourceTree = "<group>"; };
F399C6542A78933000C86979 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
@ -1815,10 +1819,12 @@
001795B01074222D00F5D044 /* testaudioinfo.c */,
F35E56CC2983130F00A43A5F /* testautomation.c */,
F35E56C42983130D00A43A5F /* testautomation_audio.c */,
F38908B42E81276900CE01D5 /* testautomation_blit.c */,
F35E56BC2983130B00A43A5F /* testautomation_clipboard.c */,
F35E56BB2983130B00A43A5F /* testautomation_events.c */,
F35E56C92983130E00A43A5F /* testautomation_guid.c */,
F35E56B72983130A00A43A5F /* testautomation_hints.c */,
F38908B52E81276900CE01D5 /* testautomation_images.h */,
F35E56BF2983130C00A43A5F /* testautomation_images.c */,
F399C6502A7892D800C86979 /* testautomation_intrinsics.c */,
F35E56B92983130B00A43A5F /* testautomation_iostream.c */,
@ -1836,6 +1842,7 @@
F35E56C82983130E00A43A5F /* testautomation_sdltest.c */,
F35E56BE2983130C00A43A5F /* testautomation_stdlib.c */,
A1A859492BC72FC20045DD6C /* testautomation_subsystems.c */,
F38908B62E81276900CE01D5 /* testautomation_suites.h */,
F35E56CB2983130F00A43A5F /* testautomation_surface.c */,
A1A8594B2BC72FC20045DD6C /* testautomation_time.c */,
F35E56BD2983130B00A43A5F /* testautomation_timer.c */,
@ -3478,6 +3485,7 @@
F35E56DE2983130F00A43A5F /* testautomation_joystick.c in Sources */,
F35E56D82983130F00A43A5F /* testautomation_images.c in Sources */,
F35E56DC2983130F00A43A5F /* testautomation_audio.c in Sources */,
F38908B72E81276900CE01D5 /* testautomation_blit.c in Sources */,
F35E56D32983130F00A43A5F /* testautomation_math.c in Sources */,
F35E56E02983130F00A43A5F /* testautomation_sdltest.c in Sources */,
F35E56D42983130F00A43A5F /* testautomation_events.c in Sources */,
@ -4061,8 +4069,8 @@
ONLY_ACTIVE_ARCH = YES;
OTHER_LDFLAGS = "$(CONFIG_FRAMEWORK_LDFLAGS)";
PRODUCT_BUNDLE_IDENTIFIER = "org.libsdl.$(PRODUCT_NAME)";
SUPPORTED_PLATFORMS = "macosx iphonesimulator iphoneos appletvsimulator appletvos";
SUPPORTS_MACCATALYST = NO;
SUPPORTED_PLATFORMS = "xrsimulator xros macosx iphonesimulator iphoneos appletvsimulator appletvos";
SUPPORTS_MACCATALYST = YES;
TARGETED_DEVICE_FAMILY = "1,2,3";
TVOS_DEPLOYMENT_TARGET = 9.0;
};
@ -4234,8 +4242,8 @@
MARKETING_VERSION = 1.0;
OTHER_LDFLAGS = "$(CONFIG_FRAMEWORK_LDFLAGS)";
PRODUCT_BUNDLE_IDENTIFIER = "org.libsdl.$(PRODUCT_NAME)";
SUPPORTED_PLATFORMS = "macosx iphonesimulator iphoneos appletvsimulator appletvos";
SUPPORTS_MACCATALYST = NO;
SUPPORTED_PLATFORMS = "xrsimulator xros macosx iphonesimulator iphoneos appletvsimulator appletvos";
SUPPORTS_MACCATALYST = YES;
TARGETED_DEVICE_FAMILY = "1,2,3";
TVOS_DEPLOYMENT_TARGET = 9.0;
};
@ -4476,7 +4484,6 @@
ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES;
EXECUTABLE_PREFIX = lib;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "watchsimulator watchos macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos";
SUPPORTS_MACCATALYST = YES;
};
name = Debug;
@ -4487,7 +4494,6 @@
ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES;
EXECUTABLE_PREFIX = lib;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "watchsimulator watchos macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos";
SUPPORTS_MACCATALYST = YES;
};
name = Release;

View file

@ -23,7 +23,7 @@
void clipboardSetText(java.lang.String);
int createCustomCursor(int[], int, int, int, int);
void destroyCustomCursor(int);
android.content.Context getContext();
android.app.Activity getContext();
boolean getManifestEnvironmentVariables();
android.view.Surface getNativeSurface();
void initTouch();

View file

@ -113,7 +113,7 @@ public class HIDDeviceManager {
// if (shouldClear) {
// SharedPreferences.Editor spedit = mSharedPreferences.edit();
// spedit.clear();
// spedit.commit();
// spedit.apply();
// }
// else
{
@ -135,7 +135,7 @@ public class HIDDeviceManager {
}
spedit.putInt(identifier, result);
spedit.commit();
spedit.apply();
return result;
}

View file

@ -4,6 +4,7 @@ import android.hardware.usb.*;
import android.os.Build;
import android.util.Log;
import java.util.Arrays;
import java.util.Locale;
class HIDDeviceUSB implements HIDDevice {
@ -31,7 +32,7 @@ class HIDDeviceUSB implements HIDDevice {
}
String getIdentifier() {
return String.format("%s/%x/%x/%d", mDevice.getDeviceName(), mDevice.getVendorId(), mDevice.getProductId(), mInterfaceIndex);
return String.format(Locale.ENGLISH, "%s/%x/%x/%d", mDevice.getDeviceName(), mDevice.getVendorId(), mDevice.getProductId(), mInterfaceIndex);
}
@Override

View file

@ -1,8 +1,8 @@
package org.libsdl.app;
import android.app.Activity;
import android.content.Context;
import java.lang.Class;
import java.lang.reflect.Method;
/**
@ -28,12 +28,12 @@ public class SDL {
}
// This function stores the current activity (SDL or not)
static public void setContext(Context context) {
static public void setContext(Activity context) {
SDLAudioManager.setContext(context);
mContext = context;
}
static public Context getContext() {
static public Activity getContext() {
return mContext;
}
@ -86,5 +86,5 @@ public class SDL {
}
}
protected static Context mContext;
protected static Activity mContext;
}

View file

@ -894,7 +894,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
protected static class SDLCommandHandler extends Handler {
@Override
public void handleMessage(Message msg) {
Context context = SDL.getContext();
Context context = getContext();
if (context == null) {
Log.e(TAG, "error handling message, getContext() returned null");
return;
@ -929,7 +929,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
SDLActivity.mFullscreenModeActive = false;
}
if (Build.VERSION.SDK_INT >= 28 /* Android 9 (Pie) */) {
if (Build.VERSION.SDK_INT >= 30 /* Android 11 (R) */) {
window.getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
}
if (Build.VERSION.SDK_INT >= 30 /* Android 11 (R) */ &&
@ -1018,7 +1018,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
}
}
if (bShouldWait && (SDLActivity.getContext() != null)) {
if (bShouldWait && (getContext() != null)) {
// We'll wait for the surfaceChanged() method, which will notify us
// when called. That way, we know our current size is really the
// size we need, instead of grabbing a size that's still got
@ -1028,9 +1028,9 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
// take a surprisingly long time for the surface resize, but
// then we'll just give up and return.
//
synchronized (SDLActivity.getContext()) {
synchronized (getContext()) {
try {
SDLActivity.getContext().wait(500);
getContext().wait(500);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
@ -1043,7 +1043,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
// C functions we call
public static native String nativeGetVersion();
public static native int nativeSetupJNI();
public static native void nativeSetupJNI();
public static native void nativeInitMainThread();
public static native void nativeCleanupMainThread();
public static native int nativeRunMain(String library, String function, Object arguments);
@ -1213,7 +1213,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
return false;
}
InputMethodManager imm = (InputMethodManager) SDL.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
InputMethodManager imm = (InputMethodManager)getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
return imm.isAcceptingText();
}
@ -1262,7 +1262,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
/**
* This method is called by SDL using JNI.
*/
public static Context getContext() {
public static Activity getContext() {
return SDL.getContext();
}
@ -1423,7 +1423,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
params.topMargin = y;
if (mTextEdit == null) {
mTextEdit = new SDLDummyEdit(SDL.getContext());
mTextEdit = new SDLDummyEdit(getContext());
mLayout.addView(mTextEdit, params);
} else {
@ -1434,7 +1434,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
mTextEdit.setVisibility(View.VISIBLE);
mTextEdit.requestFocus();
InputMethodManager imm = (InputMethodManager) SDL.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(mTextEdit, 0);
mScreenKeyboardShown = true;
@ -1928,7 +1928,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
}
if (Build.VERSION.SDK_INT >= 24 /* Android 7.0 (N) */) {
try {
mSurface.setPointerIcon(PointerIcon.getSystemIcon(SDL.getContext(), cursor_type));
mSurface.setPointerIcon(PointerIcon.getSystemIcon(getContext(), cursor_type));
} catch (Exception e) {
return false;
}
@ -2190,7 +2190,11 @@ class SDLClipboardHandler implements
}
public boolean clipboardHasText() {
return mClipMgr.hasPrimaryClip();
if (Build.VERSION.SDK_INT >= 28 /* Android 9 (P) */) {
return mClipMgr.hasPrimaryClip();
} else {
return mClipMgr.hasText();
}
}
public String clipboardGetText() {
@ -2208,10 +2212,19 @@ class SDLClipboardHandler implements
}
public void clipboardSetText(String string) {
mClipMgr.removePrimaryClipChangedListener(this);
ClipData clip = ClipData.newPlainText(null, string);
mClipMgr.setPrimaryClip(clip);
mClipMgr.addPrimaryClipChangedListener(this);
mClipMgr.removePrimaryClipChangedListener(this);
if (string.isEmpty()) {
if (Build.VERSION.SDK_INT >= 28 /* Android 9 (P) */) {
mClipMgr.clearPrimaryClip();
} else {
ClipData clip = ClipData.newPlainText(null, "");
mClipMgr.setPrimaryClip(clip);
}
} else {
ClipData clip = ClipData.newPlainText(null, string);
mClipMgr.setPrimaryClip(clip);
}
mClipMgr.addPrimaryClipChangedListener(this);
}
@Override

View file

@ -117,7 +117,7 @@ class SDLAudioManager {
}
}
static native int nativeSetupJNI();
static native void nativeSetupJNI();
static native void nativeRemoveAudioDevice(boolean recording, int deviceId);

View file

@ -20,7 +20,7 @@ import android.view.View;
public class SDLControllerManager
{
static native int nativeSetupJNI();
static native void nativeSetupJNI();
static native void nativeAddJoystick(int device_id, String name, String desc,
int vendor_id, int product_id,
@ -471,6 +471,11 @@ class SDLHapticHandler_API31 extends SDLHapticHandler {
return;
}
if (Build.VERSION.SDK_INT < 31 /* Android 12.0 (S) */) {
/* Silence 'lint' warning */
return;
}
VibratorManager manager = device.getVibratorManager();
int[] vibrators = manager.getVibratorIds();
if (vibrators.length >= 2) {
@ -483,6 +488,12 @@ class SDLHapticHandler_API31 extends SDLHapticHandler {
}
private void vibrate(Vibrator vibrator, float intensity, int length) {
if (Build.VERSION.SDK_INT < 31 /* Android 12.0 (S) */) {
/* Silence 'lint' warning */
return;
}
if (intensity == 0.0f) {
vibrator.cancel();
return;
@ -510,6 +521,12 @@ class SDLHapticHandler_API31 extends SDLHapticHandler {
class SDLHapticHandler_API26 extends SDLHapticHandler {
@Override
void run(int device_id, float intensity, int length) {
if (Build.VERSION.SDK_INT < 26 /* Android 8.0 (O) */) {
/* Silence 'lint' warning */
return;
}
SDLHaptic haptic = getHaptic(device_id);
if (haptic != null) {
if (intensity == 0.0f) {
@ -743,6 +760,11 @@ class SDLGenericMotionListener_API24 extends SDLGenericMotionListener_API14 {
@Override
float getEventX(MotionEvent event, int pointerIndex) {
if (Build.VERSION.SDK_INT < 24 /* Android 7.0 (N) */) {
/* Silence 'lint' warning */
return 0;
}
if (mRelativeModeEnabled && event.getToolType(pointerIndex) == MotionEvent.TOOL_TYPE_MOUSE) {
return event.getAxisValue(MotionEvent.AXIS_RELATIVE_X, pointerIndex);
} else {
@ -752,6 +774,11 @@ class SDLGenericMotionListener_API24 extends SDLGenericMotionListener_API14 {
@Override
float getEventY(MotionEvent event, int pointerIndex) {
if (Build.VERSION.SDK_INT < 24 /* Android 7.0 (N) */) {
/* Silence 'lint' warning */
return 0;
}
if (mRelativeModeEnabled && event.getToolType(pointerIndex) == MotionEvent.TOOL_TYPE_MOUSE) {
return event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y, pointerIndex);
} else {
@ -776,6 +803,12 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
@Override
boolean setRelativeMouseEnabled(boolean enabled) {
if (Build.VERSION.SDK_INT < 26 /* Android 8.0 (O) */) {
/* Silence 'lint' warning */
return false;
}
if (!SDLActivity.isDeXMode() || Build.VERSION.SDK_INT >= 27 /* Android 8.1 (O_MR1) */) {
if (enabled) {
SDLActivity.getContentView().requestPointerCapture();
@ -791,6 +824,12 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
@Override
void reclaimRelativeMouseModeIfNeeded() {
if (Build.VERSION.SDK_INT < 26 /* Android 8.0 (O) */) {
/* Silence 'lint' warning */
return;
}
if (mRelativeModeEnabled && !SDLActivity.isDeXMode()) {
SDLActivity.getContentView().requestPointerCapture();
}
@ -798,6 +837,10 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
@Override
boolean checkRelativeEvent(MotionEvent event) {
if (Build.VERSION.SDK_INT < 26 /* Android 8.0 (O) */) {
/* Silence 'lint' warning */
return false;
}
return event.getSource() == InputDevice.SOURCE_MOUSE_RELATIVE;
}

View file

@ -1517,7 +1517,7 @@ def main(argv=None) -> int:
if args.android_home is None or not Path(args.android_home).is_dir():
parser.error("Invalid $ANDROID_HOME or --android-home: must be a directory containing the Android SDK")
if args.android_ndk_home is None or not Path(args.android_ndk_home).is_dir():
parser.error("Invalid $ANDROID_NDK_HOME or --android_ndk_home: must be a directory containing the Android NDK")
parser.error("Invalid $ANDROID_NDK_HOME or --android-ndk-home: must be a directory containing the Android NDK")
if args.android_api is None:
with section_printer.group("Detect Android APIS"):
args.android_api = releaser._detect_android_api(android_home=args.android_home)

View file

@ -187,6 +187,11 @@ sub handle_example_dir {
$description =~ s/\s+\Z//;
}
my $short_description = "$description";
$short_description =~ s/\<br\/\>\n.*//gms;
$short_description =~ s/\A\s+//;
$short_description =~ s/\s+\Z//;
do_mkdir($dst);
do_copy($jssrc, $jsdst);
do_copy($wasmsrc, $wasmdst);
@ -222,7 +227,7 @@ sub handle_example_dir {
my $other_examples_html = "<ul>";
foreach my $example (get_examples_for_category($category)) {
$other_examples_html .= "<li><a href='/$project/$category/$example'>$category/$example</a></li>";
$other_examples_html .= "<li><a href='/$project/$category/$example/'>$category/$example</a></li>";
}
$other_examples_html .= "</ul>";
@ -238,6 +243,7 @@ sub handle_example_dir {
s/\@example_name\@/$example/g;
s/\@javascript_file\@/$jsfname/g;
s/\@htmlified_source_code\@/$htmlified_source_code/g;
s/\@short_description\@/$short_description/g;
s/\@description\@/$description/g;
s/\@preview_image\@/$preview_image/g;
s/\@other_examples_html\@/$other_examples_html/g;
@ -268,6 +274,7 @@ sub generate_example_thumbnail {
my $project = shift;
my $category = shift;
my $example = shift;
my $preloadhtmlref = shift;
my $example_no_num = "$example";
$example_no_num =~ s/\A\d+\-//;
@ -277,12 +284,14 @@ sub generate_example_thumbnail {
my $example_mouseover_html = '';
if ( -f "$examples_dir/$category/$example/onmouseover.webp" ) {
$example_mouseover_html = "onmouseover=\"this.src='/$project/$category/$example/onmouseover.webp'\" onmouseout=\"this.src='$example_image_url';\"";
$$preloadhtmlref .= " <link rel='preload' as='image' href='/$project/$category/$example/onmouseover.webp'>\n";
} elsif ( -f "$examples_dir/$category/onmouseover.webp" ) {
$example_mouseover_html = "onmouseover=\"this.src='/$project/$category/onmouseover.webp'\" onmouseout=\"this.src='$example_image_url';\"";
$$preloadhtmlref .= " <link rel='preload' as='image' href='/$project/$category/onmouseover.webp'>\n";
}
return "
<a href='/$project/$category/$example'>
<a href='/$project/$category/$example/'>
<div>
<img src='$example_image_url' $example_mouseover_html />
<div>$example_no_num</div>
@ -294,10 +303,11 @@ sub generate_example_thumbnail {
sub generate_example_thumbnails_for_category {
my $project = shift;
my $category = shift;
my $preloadhtmlref = shift;
my @examples = get_examples_for_category($category);
my $retval = '';
foreach my $example (@examples) {
$retval .= generate_example_thumbnail($project, $category, $example);
$retval .= generate_example_thumbnail($project, $category, $example, $preloadhtmlref);
}
return $retval;
}
@ -319,7 +329,8 @@ sub handle_category_dir {
closedir($dh);
my $examples_list_html = generate_example_thumbnails_for_category($project, $category);
my $preloadhtml = '';
my $examples_list_html = generate_example_thumbnails_for_category($project, $category, \$preloadhtml);
my $dst = "$output_dir/$category";
@ -339,6 +350,7 @@ sub handle_category_dir {
s/\@project_name\@/$project/g;
s/\@category_name\@/$category/g;
s/\@category_description\@/$category_description/g;
s/\@preload_images_html\@/$preloadhtml/g;
s/\@examples_list_html\@/$examples_list_html/g;
s/\@preview_image\@/$preview_image/g;
$html .= $_;
@ -390,12 +402,13 @@ while (readdir($dh)) {
closedir($dh);
# write homepage
my $homepage_list_html = "";
my $homepage_list_html = '';
my $homepage_preloadhtml = '';
foreach my $category (get_categories()) {
my $category_description = get_category_description($category);
$homepage_list_html .= "<h2>$category_description</h2>";
$homepage_list_html .= "<div class='list'>";
$homepage_list_html .= generate_example_thumbnails_for_category($project, $category);
$homepage_list_html .= generate_example_thumbnails_for_category($project, $category, \$homepage_preloadhtml);
$homepage_list_html .= "</div>";
}
@ -408,6 +421,7 @@ while (<$htmltemplate>) {
s/\@project_name\@/$project/g;
s/\@homepage_list_html\@/$homepage_list_html/g;
s/\@preview_image\@/$preview_image/g;
s/\@preload_images_html\@/$homepage_preloadhtml/g;
$html .= $_;
}
close($htmltemplate);

View file

@ -26,7 +26,6 @@ import zipfile
AAR_PATH = pathlib.Path(__file__).resolve().parent
ANDROID_ARCHS = { "armeabi-v7a", "arm64-v8a", "x86", "x86_64" }
def main():

View file

@ -1,16 +1,16 @@
# Helper for Find modules
function(get_flags_from_pkg_config _library _pc_prefix _out_prefix)
if("${_library}" MATCHES "${CMAKE_STATIC_LIBRARY_SUFFIX}$")
set(_cflags ${_pc_prefix}_STATIC_CFLAGS_OTHER)
set(_link_libraries ${_pc_prefix}_STATIC_LIBRARIES)
set(_link_options ${_pc_prefix}_STATIC_LDFLAGS_OTHER)
set(_library_dirs ${_pc_prefix}_STATIC_LIBRARY_DIRS)
else()
if(NOT "${_library}" MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$")
set(_cflags ${_pc_prefix}_CFLAGS_OTHER)
set(_link_libraries ${_pc_prefix}_LIBRARIES)
set(_link_options ${_pc_prefix}_LDFLAGS_OTHER)
set(_library_dirs ${_pc_prefix}_LIBRARY_DIRS)
else()
set(_cflags ${_pc_prefix}_STATIC_CFLAGS_OTHER)
set(_link_libraries ${_pc_prefix}_STATIC_LIBRARIES)
set(_link_options ${_pc_prefix}_STATIC_LDFLAGS_OTHER)
set(_library_dirs ${_pc_prefix}_STATIC_LIBRARY_DIRS)
endif()
# The *_LIBRARIES lists always start with the library itself

View file

@ -1,183 +1,193 @@
if(MSVC)
function(SDL_Preseed_CMakeCache)
set(COMPILER_SUPPORTS_W3 "1" CACHE INTERNAL "Test /W3")
set(COMPILER_SUPPORTS_FDIAGNOSTICS_COLOR_ALWAYS "" CACHE INTERNAL "Test COMPILER_SUPPORTS_FDIAGNOSTICS_COLOR_ALWAYS")
set(HAVE_ALLOCA_H "" CACHE INTERNAL "Have include alloca.h")
set(HAVE_AUDIOCLIENT_H "1" CACHE INTERNAL "Have include audioclient.h")
set(HAVE_D3D11_H "1" CACHE INTERNAL "Have include d3d11_1.h")
set(HAVE_D3D9_H "1" CACHE INTERNAL "Have include d3d9.h")
set(HAVE_DDRAW_H "1" CACHE INTERNAL "Have include ddraw.h")
set(HAVE_DINPUT_H "1" CACHE INTERNAL "Have include dinput.h")
set(HAVE_DSOUND_H "1" CACHE INTERNAL "Have include dsound.h")
set(HAVE_DXGI_H "1" CACHE INTERNAL "Have include dxgi.h")
set(HAVE_LIBM "" CACHE INTERNAL "Have library m")
set(HAVE_MALLOC "1" CACHE INTERNAL "Have include malloc.h")
set(HAVE_MMDEVICEAPI_H "1" CACHE INTERNAL "Have include mmdeviceapi.h")
set(HAVE_SENSORSAPI_H "1" CACHE INTERNAL "Have include sensorsapi.h")
set(HAVE_SHELLSCALINGAPI_H "1" CACHE INTERNAL "Have include shellscalingapi.h")
set(HAVE_TPCSHRD_H "1" CACHE INTERNAL "Have include tpcshrd.h")
set(HAVE_WIN32_CC "1" CACHE INTERNAL "Test HAVE_WIN32_CC")
set(HAVE_XINPUT_H "1" CACHE INTERNAL "Test HAVE_XINPUT_H")
set(LIBC_HAS_ABS "1" CACHE INTERNAL "Have symbol abs")
set(LIBC_HAS_ACOS "1" CACHE INTERNAL "Have symbol acos")
set(LIBC_HAS_ACOSF "1" CACHE INTERNAL "Have symbol acosf")
set(LIBC_HAS_ASIN "1" CACHE INTERNAL "Have symbol asin")
set(LIBC_HAS_ASINF "1" CACHE INTERNAL "Have symbol asinf")
set(LIBC_HAS_ATAN "1" CACHE INTERNAL "Have symbol atan")
set(LIBC_HAS_ATAN2 "1" CACHE INTERNAL "Have symbol atan2")
set(LIBC_HAS_ATAN2F "1" CACHE INTERNAL "Have symbol atan2f")
set(LIBC_HAS_ATANF "1" CACHE INTERNAL "Have symbol atanf")
set(LIBC_HAS_ATOF "1" CACHE INTERNAL "Have symbol atof")
set(LIBC_HAS_ATOI "1" CACHE INTERNAL "Have symbol atoi")
set(LIBC_HAS_BCOPY "" CACHE INTERNAL "Have symbol bcopy")
set(LIBC_HAS_CALLOC "1" CACHE INTERNAL "Have symbol calloc")
set(LIBC_HAS_CEIL "1" CACHE INTERNAL "Have symbol ceil")
set(LIBC_HAS_CEILF "1" CACHE INTERNAL "Have symbol ceilf")
set(LIBC_HAS_COPYSIGN "1" CACHE INTERNAL "Have symbol copysign")
set(LIBC_HAS_COPYSIGNF "1" CACHE INTERNAL "Have symbol copysignf")
set(LIBC_HAS_COS "1" CACHE INTERNAL "Have symbol cos")
set(LIBC_HAS_COSF "1" CACHE INTERNAL "Have symbol cosf")
set(LIBC_HAS_EXP "1" CACHE INTERNAL "Have symbol exp")
set(LIBC_HAS_EXPF "1" CACHE INTERNAL "Have symbol expf")
set(LIBC_HAS_FABS "1" CACHE INTERNAL "Have symbol fabs")
set(LIBC_HAS_FABSF "1" CACHE INTERNAL "Have symbol fabsf")
set(LIBC_HAS_FLOAT_H "1" CACHE INTERNAL "Have include float.h")
set(LIBC_HAS_FLOOR "1" CACHE INTERNAL "Have symbol floor")
set(LIBC_HAS_FLOORF "1" CACHE INTERNAL "Have symbol floorf")
set(LIBC_HAS_FMOD "1" CACHE INTERNAL "Have symbol fmod")
set(LIBC_HAS_FMODF "1" CACHE INTERNAL "Have symbol fmodf")
set(LIBC_HAS_FOPEN64 "" CACHE INTERNAL "Have symbol fopen64")
set(LIBC_HAS_FREE "1" CACHE INTERNAL "Have symbol free")
set(LIBC_HAS_FSEEKO "" CACHE INTERNAL "Have symbol fseeko")
set(LIBC_HAS_FSEEKO64 "" CACHE INTERNAL "Have symbol fseeko64")
set(LIBC_HAS_GETENV "1" CACHE INTERNAL "Have symbol getenv")
set(LIBC_HAS_ICONV_H "" CACHE INTERNAL "Have include iconv.h")
set(LIBC_HAS_INDEX "" CACHE INTERNAL "Have symbol index")
set(LIBC_HAS_INTTYPES_H "1" CACHE INTERNAL "Have include inttypes.h")
set(LIBC_HAS_ISINF "1" CACHE INTERNAL "Have include isinf(double)")
set(LIBC_ISINF_HANDLES_FLOAT "1" CACHE INTERNAL "Have include isinf(float)")
set(LIBC_HAS_ISINFF "" CACHE INTERNAL "Have include isinff(float)")
set(LIBC_HAS_ISNAN "1" CACHE INTERNAL "Have include isnan(double)")
set(LIBC_ISNAN_HANDLES_FLOAT "1" CACHE INTERNAL "Have include isnan(float)")
set(LIBC_HAS_ISNANF "" CACHE INTERNAL "Have include isnanf(float)")
set(LIBC_HAS_ITOA "1" CACHE INTERNAL "Have symbol itoa")
set(LIBC_HAS_LIMITS_H "1" CACHE INTERNAL "Have include limits.h")
set(LIBC_HAS_LOG "1" CACHE INTERNAL "Have symbol log")
set(LIBC_HAS_LOG10 "1" CACHE INTERNAL "Have symbol log10")
set(LIBC_HAS_LOG10F "1" CACHE INTERNAL "Have symbol log10f")
set(LIBC_HAS_LOGF "1" CACHE INTERNAL "Have symbol logf")
set(LIBC_HAS_LROUND "1" CACHE INTERNAL "Have symbol lround")
set(LIBC_HAS_LROUNDF "1" CACHE INTERNAL "Have symbol lroundf")
set(LIBC_HAS_MALLOC "1" CACHE INTERNAL "Have symbol malloc")
set(LIBC_HAS_MALLOC_H "1" CACHE INTERNAL "Have include malloc.h")
set(LIBC_HAS_MATH_H "1" CACHE INTERNAL "Have include math.h")
set(LIBC_HAS_MEMCMP "1" CACHE INTERNAL "Have symbol memcmp")
set(LIBC_HAS_MEMCPY "1" CACHE INTERNAL "Have symbol memcpy")
set(LIBC_HAS_MEMMOVE "1" CACHE INTERNAL "Have symbol memmove")
set(LIBC_HAS_MEMORY_H "1" CACHE INTERNAL "Have include memory.h")
set(LIBC_HAS_MEMSET "1" CACHE INTERNAL "Have symbol memset")
set(LIBC_HAS_MODF "1" CACHE INTERNAL "Have symbol modf")
set(LIBC_HAS_MODFF "1" CACHE INTERNAL "Have symbol modff")
set(LIBC_HAS_POW "1" CACHE INTERNAL "Have symbol pow")
set(LIBC_HAS_POWF "1" CACHE INTERNAL "Have symbol powf")
set(LIBC_HAS_PUTENV "1" CACHE INTERNAL "Have symbol putenv")
set(LIBC_HAS_REALLOC "1" CACHE INTERNAL "Have symbol realloc")
set(LIBC_HAS_RINDEX "" CACHE INTERNAL "Have symbol rindex")
set(LIBC_HAS_ROUND "1" CACHE INTERNAL "Have symbol round")
set(LIBC_HAS_ROUNDF "1" CACHE INTERNAL "Have symbol roundf")
set(LIBC_HAS_SCALBN "1" CACHE INTERNAL "Have symbol scalbn")
set(LIBC_HAS_SCALBNF "1" CACHE INTERNAL "Have symbol scalbnf")
set(LIBC_HAS_SETENV "" CACHE INTERNAL "Have symbol setenv")
set(LIBC_HAS_SIGNAL_H "1" CACHE INTERNAL "Have include signal.h")
set(LIBC_HAS_SIN "1" CACHE INTERNAL "Have symbol sin")
set(LIBC_HAS_SINF "1" CACHE INTERNAL "Have symbol sinf")
set(LIBC_HAS_SQR "" CACHE INTERNAL "Have symbol sqr")
set(LIBC_HAS_SQRT "1" CACHE INTERNAL "Have symbol sqrt")
set(LIBC_HAS_SQRTF "1" CACHE INTERNAL "Have symbol sqrtf")
set(LIBC_HAS_SSCANF "1" CACHE INTERNAL "Have symbol sscanf")
set(LIBC_HAS_STDARG_H "1" CACHE INTERNAL "Have include stdarg.h")
set(LIBC_HAS_STDBOOL_H "1" CACHE INTERNAL "Have include stdbool.h")
set(LIBC_HAS_STDDEF_H "1" CACHE INTERNAL "Have include stddef.h")
set(LIBC_HAS_STDINT_H "1" CACHE INTERNAL "Have include stdint.h")
set(LIBC_HAS_STDIO_H "1" CACHE INTERNAL "Have include stdio.h")
set(LIBC_HAS_STDLIB_H "1" CACHE INTERNAL "Have include stdlib.h")
set(LIBC_HAS_STRCHR "1" CACHE INTERNAL "Have symbol strchr")
set(LIBC_HAS_STRCMP "1" CACHE INTERNAL "Have symbol strcmp")
set(LIBC_HAS_STRINGS_H "" CACHE INTERNAL "Have include strings.h")
set(LIBC_HAS_STRING_H "1" CACHE INTERNAL "Have include string.h")
set(LIBC_HAS_STRLCAT "" CACHE INTERNAL "Have symbol strlcat")
set(LIBC_HAS_STRLCPY "" CACHE INTERNAL "Have symbol strlcpy")
set(LIBC_HAS_STRLEN "1" CACHE INTERNAL "Have symbol strlen")
set(LIBC_HAS_STRNCMP "1" CACHE INTERNAL "Have symbol strncmp")
set(LIBC_HAS_STRNLEN "1" CACHE INTERNAL "Have symbol strnlen")
set(LIBC_HAS_STRNSTR "" CACHE INTERNAL "Have symbol strnstr")
set(LIBC_HAS_STRPBRK "1" CACHE INTERNAL "Have symbol strpbrk")
set(LIBC_HAS_STRRCHR "1" CACHE INTERNAL "Have symbol strrchr")
set(LIBC_HAS_STRSTR "1" CACHE INTERNAL "Have symbol strstr")
set(LIBC_HAS_STRTOD "1" CACHE INTERNAL "Have symbol strtod")
set(LIBC_HAS_STRTOK_R "" CACHE INTERNAL "Have symbol strtok_r")
set(LIBC_HAS_STRTOL "1" CACHE INTERNAL "Have symbol strtol")
set(LIBC_HAS_STRTOLL "1" CACHE INTERNAL "Have symbol strtoll")
set(LIBC_HAS_STRTOUL "1" CACHE INTERNAL "Have symbol strtoul")
set(LIBC_HAS_STRTOULL "1" CACHE INTERNAL "Have symbol strtoull")
set(LIBC_HAS_SYS_TYPES_H "1" CACHE INTERNAL "Have include sys/types.h")
set(LIBC_HAS_TAN "1" CACHE INTERNAL "Have symbol tan")
set(LIBC_HAS_TANF "1" CACHE INTERNAL "Have symbol tanf")
set(LIBC_HAS_TIME_H "1" CACHE INTERNAL "Have include time.h")
set(LIBC_HAS_TRUNC "1" CACHE INTERNAL "Have symbol trunc")
set(LIBC_HAS_TRUNCF "1" CACHE INTERNAL "Have symbol truncf")
set(LIBC_HAS_UNSETENV "" CACHE INTERNAL "Have symbol unsetenv")
set(LIBC_HAS_VSNPRINTF "1" CACHE INTERNAL "Have symbol vsnprintf")
set(LIBC_HAS_VSSCANF "1" CACHE INTERNAL "Have symbol vsscanf")
set(LIBC_HAS_WCHAR_H "1" CACHE INTERNAL "Have include wchar.h")
set(LIBC_HAS_WCSCMP "1" CACHE INTERNAL "Have symbol wcscmp")
set(LIBC_HAS_WCSDUP "1" CACHE INTERNAL "Have symbol wcsdup")
set(LIBC_HAS_WCSLCAT "" CACHE INTERNAL "Have symbol wcslcat")
set(LIBC_HAS_WCSLCPY "" CACHE INTERNAL "Have symbol wcslcpy")
set(LIBC_HAS_WCSLEN "1" CACHE INTERNAL "Have symbol wcslen")
set(LIBC_HAS_WCSNCMP "1" CACHE INTERNAL "Have symbol wcsncmp")
set(LIBC_HAS_WCSNLEN "1" CACHE INTERNAL "Have symbol wcsnlen")
set(LIBC_HAS_WCSSTR "1" CACHE INTERNAL "Have symbol wcsstr")
set(LIBC_HAS_WCSTOL "1" CACHE INTERNAL "Have symbol wcstol")
set(LIBC_HAS__EXIT "1" CACHE INTERNAL "Have symbol _Exit")
set(LIBC_HAS__I64TOA "1" CACHE INTERNAL "Have symbol _i64toa")
set(LIBC_HAS__LTOA "1" CACHE INTERNAL "Have symbol _ltoa")
set(LIBC_HAS__STRREV "1" CACHE INTERNAL "Have symbol _strrev")
set(LIBC_HAS__UI64TOA "1" CACHE INTERNAL "Have symbol _ui64toa")
set(LIBC_HAS__UITOA "" CACHE INTERNAL "Have symbol _uitoa")
set(LIBC_HAS__ULTOA "1" CACHE INTERNAL "Have symbol _ultoa")
set(LIBC_HAS__WCSDUP "1" CACHE INTERNAL "Have symbol _wcsdup")
set(LIBC_IS_GLIBC "" CACHE INTERNAL "Have symbol __GLIBC__")
set(_ALLOCA_IN_MALLOC_H "" CACHE INTERNAL "Have symbol _alloca")
check_c_source_compiles("
#include <sdkddkver.h>
#if _WIN32_WINNT < 0x0A00
#error Preseeding is only supported for MSVC supporting Windows 10 or higher
#endif
int main(int argc, char **argv) { return 0; }
" CAN_PRESEED
)
if(CAN_PRESEED)
set(COMPILER_SUPPORTS_W3 "1" CACHE INTERNAL "Test /W3")
set(COMPILER_SUPPORTS_FDIAGNOSTICS_COLOR_ALWAYS "" CACHE INTERNAL "Test COMPILER_SUPPORTS_FDIAGNOSTICS_COLOR_ALWAYS")
set(HAVE_ALLOCA_H "" CACHE INTERNAL "Have include alloca.h")
set(HAVE_AUDIOCLIENT_H "1" CACHE INTERNAL "Have include audioclient.h")
set(HAVE_D3D11_H "1" CACHE INTERNAL "Have include d3d11_1.h")
set(HAVE_D3D9_H "1" CACHE INTERNAL "Have include d3d9.h")
set(HAVE_DDRAW_H "1" CACHE INTERNAL "Have include ddraw.h")
set(HAVE_DINPUT_H "1" CACHE INTERNAL "Have include dinput.h")
set(HAVE_DSOUND_H "1" CACHE INTERNAL "Have include dsound.h")
set(HAVE_DXGI_H "1" CACHE INTERNAL "Have include dxgi.h")
set(HAVE_LIBM "" CACHE INTERNAL "Have library m")
set(HAVE_MALLOC "1" CACHE INTERNAL "Have include malloc.h")
set(HAVE_MMDEVICEAPI_H "1" CACHE INTERNAL "Have include mmdeviceapi.h")
set(HAVE_SENSORSAPI_H "1" CACHE INTERNAL "Have include sensorsapi.h")
set(HAVE_SHELLSCALINGAPI_H "1" CACHE INTERNAL "Have include shellscalingapi.h")
set(HAVE_TPCSHRD_H "1" CACHE INTERNAL "Have include tpcshrd.h")
set(HAVE_WIN32_CC "1" CACHE INTERNAL "Test HAVE_WIN32_CC")
set(HAVE_XINPUT_H "1" CACHE INTERNAL "Test HAVE_XINPUT_H")
set(LIBC_HAS_ABS "1" CACHE INTERNAL "Have symbol abs")
set(LIBC_HAS_ACOS "1" CACHE INTERNAL "Have symbol acos")
set(LIBC_HAS_ACOSF "1" CACHE INTERNAL "Have symbol acosf")
set(LIBC_HAS_ASIN "1" CACHE INTERNAL "Have symbol asin")
set(LIBC_HAS_ASINF "1" CACHE INTERNAL "Have symbol asinf")
set(LIBC_HAS_ATAN "1" CACHE INTERNAL "Have symbol atan")
set(LIBC_HAS_ATAN2 "1" CACHE INTERNAL "Have symbol atan2")
set(LIBC_HAS_ATAN2F "1" CACHE INTERNAL "Have symbol atan2f")
set(LIBC_HAS_ATANF "1" CACHE INTERNAL "Have symbol atanf")
set(LIBC_HAS_ATOF "1" CACHE INTERNAL "Have symbol atof")
set(LIBC_HAS_ATOI "1" CACHE INTERNAL "Have symbol atoi")
set(LIBC_HAS_BCOPY "" CACHE INTERNAL "Have symbol bcopy")
set(LIBC_HAS_CALLOC "1" CACHE INTERNAL "Have symbol calloc")
set(LIBC_HAS_CEIL "1" CACHE INTERNAL "Have symbol ceil")
set(LIBC_HAS_CEILF "1" CACHE INTERNAL "Have symbol ceilf")
set(LIBC_HAS_COPYSIGN "1" CACHE INTERNAL "Have symbol copysign")
set(LIBC_HAS_COPYSIGNF "1" CACHE INTERNAL "Have symbol copysignf")
set(LIBC_HAS_COS "1" CACHE INTERNAL "Have symbol cos")
set(LIBC_HAS_COSF "1" CACHE INTERNAL "Have symbol cosf")
set(LIBC_HAS_EXP "1" CACHE INTERNAL "Have symbol exp")
set(LIBC_HAS_EXPF "1" CACHE INTERNAL "Have symbol expf")
set(LIBC_HAS_FABS "1" CACHE INTERNAL "Have symbol fabs")
set(LIBC_HAS_FABSF "1" CACHE INTERNAL "Have symbol fabsf")
set(LIBC_HAS_FLOAT_H "1" CACHE INTERNAL "Have include float.h")
set(LIBC_HAS_FLOOR "1" CACHE INTERNAL "Have symbol floor")
set(LIBC_HAS_FLOORF "1" CACHE INTERNAL "Have symbol floorf")
set(LIBC_HAS_FMOD "1" CACHE INTERNAL "Have symbol fmod")
set(LIBC_HAS_FMODF "1" CACHE INTERNAL "Have symbol fmodf")
set(LIBC_HAS_FOPEN64 "" CACHE INTERNAL "Have symbol fopen64")
set(LIBC_HAS_FREE "1" CACHE INTERNAL "Have symbol free")
set(LIBC_HAS_FSEEKO "" CACHE INTERNAL "Have symbol fseeko")
set(LIBC_HAS_FSEEKO64 "" CACHE INTERNAL "Have symbol fseeko64")
set(LIBC_HAS_GETENV "1" CACHE INTERNAL "Have symbol getenv")
set(LIBC_HAS_ICONV_H "" CACHE INTERNAL "Have include iconv.h")
set(LIBC_HAS_INDEX "" CACHE INTERNAL "Have symbol index")
set(LIBC_HAS_INTTYPES_H "1" CACHE INTERNAL "Have include inttypes.h")
set(LIBC_HAS_ISINF "1" CACHE INTERNAL "Have include isinf(double)")
set(LIBC_ISINF_HANDLES_FLOAT "1" CACHE INTERNAL "Have include isinf(float)")
set(LIBC_HAS_ISINFF "" CACHE INTERNAL "Have include isinff(float)")
set(LIBC_HAS_ISNAN "1" CACHE INTERNAL "Have include isnan(double)")
set(LIBC_ISNAN_HANDLES_FLOAT "1" CACHE INTERNAL "Have include isnan(float)")
set(LIBC_HAS_ISNANF "" CACHE INTERNAL "Have include isnanf(float)")
set(LIBC_HAS_ITOA "1" CACHE INTERNAL "Have symbol itoa")
set(LIBC_HAS_LIMITS_H "1" CACHE INTERNAL "Have include limits.h")
set(LIBC_HAS_LOG "1" CACHE INTERNAL "Have symbol log")
set(LIBC_HAS_LOG10 "1" CACHE INTERNAL "Have symbol log10")
set(LIBC_HAS_LOG10F "1" CACHE INTERNAL "Have symbol log10f")
set(LIBC_HAS_LOGF "1" CACHE INTERNAL "Have symbol logf")
set(LIBC_HAS_LROUND "1" CACHE INTERNAL "Have symbol lround")
set(LIBC_HAS_LROUNDF "1" CACHE INTERNAL "Have symbol lroundf")
set(LIBC_HAS_MALLOC "1" CACHE INTERNAL "Have symbol malloc")
set(LIBC_HAS_MALLOC_H "1" CACHE INTERNAL "Have include malloc.h")
set(LIBC_HAS_MATH_H "1" CACHE INTERNAL "Have include math.h")
set(LIBC_HAS_MEMCMP "1" CACHE INTERNAL "Have symbol memcmp")
set(LIBC_HAS_MEMCPY "1" CACHE INTERNAL "Have symbol memcpy")
set(LIBC_HAS_MEMMOVE "1" CACHE INTERNAL "Have symbol memmove")
set(LIBC_HAS_MEMORY_H "1" CACHE INTERNAL "Have include memory.h")
set(LIBC_HAS_MEMSET "1" CACHE INTERNAL "Have symbol memset")
set(LIBC_HAS_MODF "1" CACHE INTERNAL "Have symbol modf")
set(LIBC_HAS_MODFF "1" CACHE INTERNAL "Have symbol modff")
set(LIBC_HAS_POW "1" CACHE INTERNAL "Have symbol pow")
set(LIBC_HAS_POWF "1" CACHE INTERNAL "Have symbol powf")
set(LIBC_HAS_PUTENV "1" CACHE INTERNAL "Have symbol putenv")
set(LIBC_HAS_REALLOC "1" CACHE INTERNAL "Have symbol realloc")
set(LIBC_HAS_RINDEX "" CACHE INTERNAL "Have symbol rindex")
set(LIBC_HAS_ROUND "1" CACHE INTERNAL "Have symbol round")
set(LIBC_HAS_ROUNDF "1" CACHE INTERNAL "Have symbol roundf")
set(LIBC_HAS_SCALBN "1" CACHE INTERNAL "Have symbol scalbn")
set(LIBC_HAS_SCALBNF "1" CACHE INTERNAL "Have symbol scalbnf")
set(LIBC_HAS_SETENV "" CACHE INTERNAL "Have symbol setenv")
set(LIBC_HAS_SIGNAL_H "1" CACHE INTERNAL "Have include signal.h")
set(LIBC_HAS_SIN "1" CACHE INTERNAL "Have symbol sin")
set(LIBC_HAS_SINF "1" CACHE INTERNAL "Have symbol sinf")
set(LIBC_HAS_SQR "" CACHE INTERNAL "Have symbol sqr")
set(LIBC_HAS_SQRT "1" CACHE INTERNAL "Have symbol sqrt")
set(LIBC_HAS_SQRTF "1" CACHE INTERNAL "Have symbol sqrtf")
set(LIBC_HAS_SSCANF "1" CACHE INTERNAL "Have symbol sscanf")
set(LIBC_HAS_STDARG_H "1" CACHE INTERNAL "Have include stdarg.h")
set(LIBC_HAS_STDBOOL_H "1" CACHE INTERNAL "Have include stdbool.h")
set(LIBC_HAS_STDDEF_H "1" CACHE INTERNAL "Have include stddef.h")
set(LIBC_HAS_STDINT_H "1" CACHE INTERNAL "Have include stdint.h")
set(LIBC_HAS_STDIO_H "1" CACHE INTERNAL "Have include stdio.h")
set(LIBC_HAS_STDLIB_H "1" CACHE INTERNAL "Have include stdlib.h")
set(LIBC_HAS_STRCHR "1" CACHE INTERNAL "Have symbol strchr")
set(LIBC_HAS_STRCMP "1" CACHE INTERNAL "Have symbol strcmp")
set(LIBC_HAS_STRINGS_H "" CACHE INTERNAL "Have include strings.h")
set(LIBC_HAS_STRING_H "1" CACHE INTERNAL "Have include string.h")
set(LIBC_HAS_STRLCAT "" CACHE INTERNAL "Have symbol strlcat")
set(LIBC_HAS_STRLCPY "" CACHE INTERNAL "Have symbol strlcpy")
set(LIBC_HAS_STRLEN "1" CACHE INTERNAL "Have symbol strlen")
set(LIBC_HAS_STRNCMP "1" CACHE INTERNAL "Have symbol strncmp")
set(LIBC_HAS_STRNLEN "1" CACHE INTERNAL "Have symbol strnlen")
set(LIBC_HAS_STRNSTR "" CACHE INTERNAL "Have symbol strnstr")
set(LIBC_HAS_STRPBRK "1" CACHE INTERNAL "Have symbol strpbrk")
set(LIBC_HAS_STRRCHR "1" CACHE INTERNAL "Have symbol strrchr")
set(LIBC_HAS_STRSTR "1" CACHE INTERNAL "Have symbol strstr")
set(LIBC_HAS_STRTOD "1" CACHE INTERNAL "Have symbol strtod")
set(LIBC_HAS_STRTOK_R "" CACHE INTERNAL "Have symbol strtok_r")
set(LIBC_HAS_STRTOL "1" CACHE INTERNAL "Have symbol strtol")
set(LIBC_HAS_STRTOLL "1" CACHE INTERNAL "Have symbol strtoll")
set(LIBC_HAS_STRTOUL "1" CACHE INTERNAL "Have symbol strtoul")
set(LIBC_HAS_STRTOULL "1" CACHE INTERNAL "Have symbol strtoull")
set(LIBC_HAS_SYS_TYPES_H "1" CACHE INTERNAL "Have include sys/types.h")
set(LIBC_HAS_TAN "1" CACHE INTERNAL "Have symbol tan")
set(LIBC_HAS_TANF "1" CACHE INTERNAL "Have symbol tanf")
set(LIBC_HAS_TIME_H "1" CACHE INTERNAL "Have include time.h")
set(LIBC_HAS_TRUNC "1" CACHE INTERNAL "Have symbol trunc")
set(LIBC_HAS_TRUNCF "1" CACHE INTERNAL "Have symbol truncf")
set(LIBC_HAS_UNSETENV "" CACHE INTERNAL "Have symbol unsetenv")
set(LIBC_HAS_VSNPRINTF "1" CACHE INTERNAL "Have symbol vsnprintf")
set(LIBC_HAS_VSSCANF "1" CACHE INTERNAL "Have symbol vsscanf")
set(LIBC_HAS_WCHAR_H "1" CACHE INTERNAL "Have include wchar.h")
set(LIBC_HAS_WCSCMP "1" CACHE INTERNAL "Have symbol wcscmp")
set(LIBC_HAS_WCSDUP "1" CACHE INTERNAL "Have symbol wcsdup")
set(LIBC_HAS_WCSLCAT "" CACHE INTERNAL "Have symbol wcslcat")
set(LIBC_HAS_WCSLCPY "" CACHE INTERNAL "Have symbol wcslcpy")
set(LIBC_HAS_WCSLEN "1" CACHE INTERNAL "Have symbol wcslen")
set(LIBC_HAS_WCSNCMP "1" CACHE INTERNAL "Have symbol wcsncmp")
set(LIBC_HAS_WCSNLEN "1" CACHE INTERNAL "Have symbol wcsnlen")
set(LIBC_HAS_WCSSTR "1" CACHE INTERNAL "Have symbol wcsstr")
set(LIBC_HAS_WCSTOL "1" CACHE INTERNAL "Have symbol wcstol")
set(LIBC_HAS__EXIT "1" CACHE INTERNAL "Have symbol _Exit")
set(LIBC_HAS__I64TOA "1" CACHE INTERNAL "Have symbol _i64toa")
set(LIBC_HAS__LTOA "1" CACHE INTERNAL "Have symbol _ltoa")
set(LIBC_HAS__STRREV "1" CACHE INTERNAL "Have symbol _strrev")
set(LIBC_HAS__UI64TOA "1" CACHE INTERNAL "Have symbol _ui64toa")
set(LIBC_HAS__UITOA "" CACHE INTERNAL "Have symbol _uitoa")
set(LIBC_HAS__ULTOA "1" CACHE INTERNAL "Have symbol _ultoa")
set(LIBC_HAS__WCSDUP "1" CACHE INTERNAL "Have symbol _wcsdup")
set(LIBC_IS_GLIBC "" CACHE INTERNAL "Have symbol __GLIBC__")
set(_ALLOCA_IN_MALLOC_H "" CACHE INTERNAL "Have symbol _alloca")
if(CHECK_CPU_ARCHITECTURE_X86)
set(COMPILER_SUPPORTS_AVX "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_AVX")
set(COMPILER_SUPPORTS_AVX2 "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_AVX2")
set(COMPILER_SUPPORTS_MMX "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_MMX")
set(COMPILER_SUPPORTS_SSE "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE")
set(COMPILER_SUPPORTS_SSE2 "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE2")
set(COMPILER_SUPPORTS_SSE3 "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE3")
set(COMPILER_SUPPORTS_SSE4_1 "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE4_1")
set(COMPILER_SUPPORTS_SSE4_2 "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE4_2")
endif()
if(CHECK_CPU_ARCHITECTURE_X86)
set(COMPILER_SUPPORTS_AVX "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_AVX")
set(COMPILER_SUPPORTS_AVX2 "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_AVX2")
set(COMPILER_SUPPORTS_MMX "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_MMX")
set(COMPILER_SUPPORTS_SSE "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE")
set(COMPILER_SUPPORTS_SSE2 "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE2")
set(COMPILER_SUPPORTS_SSE3 "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE3")
set(COMPILER_SUPPORTS_SSE4_1 "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE4_1")
set(COMPILER_SUPPORTS_SSE4_2 "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE4_2")
endif()
if(CHECK_CPU_ARCHITECTURE_X64)
set(COMPILER_SUPPORTS_AVX "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_AVX")
set(COMPILER_SUPPORTS_AVX2 "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_AVX2")
set(COMPILER_SUPPORTS_MMX "" CACHE INTERNAL "Test COMPILER_SUPPORTS_MMX")
set(COMPILER_SUPPORTS_SSE "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE")
set(COMPILER_SUPPORTS_SSE2 "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE2")
set(COMPILER_SUPPORTS_SSE3 "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE3")
set(COMPILER_SUPPORTS_SSE4_1 "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE4_1")
set(COMPILER_SUPPORTS_SSE4_2 "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE4_2")
endif()
if(CHECK_CPU_ARCHITECTURE_X64)
set(COMPILER_SUPPORTS_AVX "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_AVX")
set(COMPILER_SUPPORTS_AVX2 "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_AVX2")
set(COMPILER_SUPPORTS_MMX "" CACHE INTERNAL "Test COMPILER_SUPPORTS_MMX")
set(COMPILER_SUPPORTS_SSE "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE")
set(COMPILER_SUPPORTS_SSE2 "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE2")
set(COMPILER_SUPPORTS_SSE3 "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE3")
set(COMPILER_SUPPORTS_SSE4_1 "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE4_1")
set(COMPILER_SUPPORTS_SSE4_2 "1" CACHE INTERNAL "Test COMPILER_SUPPORTS_SSE4_2")
endif()
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "19.1")
set(HAVE_ROAPI_H "1" CACHE INTERNAL "Have include roapi.h")
set(HAVE_WINDOWS_GAMING_INPUT_H "1" CACHE INTERNAL "Test HAVE_WINDOWS_GAMING_INPUT_H")
else()
set(HAVE_ROAPI_H "" CACHE INTERNAL "Have include roapi.h")
set(HAVE_WINDOWS_GAMING_INPUT_H "" CACHE INTERNAL "Test HAVE_WINDOWS_GAMING_INPUT_H")
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "19.1")
set(HAVE_ROAPI_H "1" CACHE INTERNAL "Have include roapi.h")
set(HAVE_WINDOWS_GAMING_INPUT_H "1" CACHE INTERNAL "Test HAVE_WINDOWS_GAMING_INPUT_H")
else()
set(HAVE_ROAPI_H "" CACHE INTERNAL "Have include roapi.h")
set(HAVE_WINDOWS_GAMING_INPUT_H "" CACHE INTERNAL "Test HAVE_WINDOWS_GAMING_INPUT_H")
endif()
endif()
endfunction()
endif()

View file

@ -334,6 +334,29 @@ if(APPLE)
endif()
endif()
function(PrintEnabledBackends _SUBSYS _REGEXP)
get_cmake_property(_ALLVARS VARIABLES)
foreach(_VAR IN LISTS _ALLVARS)
if(_VAR AND _VAR MATCHES "${_REGEXP}")
string(TOLOWER "${CMAKE_MATCH_1}" _LOWERED)
if(NOT _LOWERED MATCHES "available|default|dynamic") # a little hack
if(${_VAR}_DYNAMIC)
list(APPEND _ENABLED_BACKENDS "${_LOWERED}(dynamic)")
else()
list(APPEND _ENABLED_BACKENDS "${_LOWERED}")
endif()
endif()
endif()
endforeach()
if(_ENABLED_BACKENDS STREQUAL "")
set(_SPACEDOUT "(none)")
else()
string(REPLACE ";" " " _SPACEDOUT "${_ENABLED_BACKENDS}")
endif()
message(STATUS " ${_SUBSYS}: ${_SPACEDOUT}")
endfunction()
function(SDL_PrintSummary)
##### Info output #####
message(STATUS "")
@ -366,6 +389,18 @@ function(SDL_PrintSummary)
message(STATUS " Build libraries as Apple Framework: ${SDL_FRAMEWORK}")
endif()
message(STATUS "")
message(STATUS "Enabled backends:")
PrintEnabledBackends("Video drivers" "^SDL_VIDEO_DRIVER_([A-Z0-9]*)$")
if(SDL_VIDEO_DRIVER_X11)
PrintEnabledBackends("X11 libraries" "^SDL_VIDEO_DRIVER_X11_([A-Z0-9]*)$")
endif()
PrintEnabledBackends("Render drivers" "^SDL_VIDEO_RENDER_([A-Z0-9_]*)$")
PrintEnabledBackends("GPU drivers" "^SDL_GPU_([A-Z0-9]*)$")
PrintEnabledBackends("Audio drivers" "^SDL_AUDIO_DRIVER_([A-Z0-9]*)$")
PrintEnabledBackends("Joystick drivers" "^SDL_JOYSTICK_([A-Z0-9]*)$")
message(STATUS "")
if(UNIX)
message(STATUS "If something was not detected, although the libraries")
message(STATUS "were installed, then make sure you have set the")

View file

@ -1,6 +1,6 @@
function(SDL_DetectTargetCPUArchitectures DETECTED_ARCHS)
set(known_archs EMSCRIPTEN ARM32 ARM64 ARM64EC LOONGARCH64 POWERPC32 POWERPC64 X86 X64)
set(known_archs EMSCRIPTEN ARM32 ARM64 ARM64EC LOONGARCH64 POWERPC32 POWERPC64 RISCV32 RISCV64 X86 X64)
if(APPLE AND CMAKE_OSX_ARCHITECTURES)
foreach(known_arch IN LISTS known_archs)
@ -39,6 +39,8 @@ function(SDL_DetectTargetCPUArchitectures DETECTED_ARCHS)
set(arch_check_LOONGARCH64 "defined(__loongarch64)")
set(arch_check_POWERPC32 "(defined(__PPC__) || defined(__powerpc__)) && !defined(__powerpc64__)")
set(arch_check_POWERPC64 "defined(__PPC64__) || defined(__powerpc64__)")
set(arch_check_RISCV32 "defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 32")
set(arch_check_RISCV64 "defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 64")
set(arch_check_X86 "defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) ||defined( __i386) || defined(_M_IX86)")
set(arch_check_X64 "(defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)) && !defined(_M_ARM64EC)")

View file

@ -598,7 +598,7 @@ The only caveat is that the APK's support a single architecture.
When configuring the CMake project, you need to use the Android NDK CMake toolchain, and pass the Android home path through `SDL_ANDROID_HOME`.
```
cmake .. -DCMAKE_TOOLCHAIN_FILE=<path/to/android.toolchain.cmake> -DANDROID_ABI=<android-abi> -DSDL_ANDROID_HOME=<path-to-android-sdk-home> -DANDROID_PLATFORM=23 -DSDL_TESTS=ON
cmake .. -DCMAKE_TOOLCHAIN_FILE=<path/to/android.toolchain.cmake> -DANDROID_ABI=<android-abi> -DSDL_ANDROID_HOME=<path-to-android-sdk-home> -DANDROID_PLATFORM=21 -DSDL_TESTS=ON
```
Remarks:

View file

@ -274,6 +274,23 @@ comment. So don't mention the type a second time in the documentation if
possible. It looks cluttered and repetitive to do so.
## Keep `\param` and `\returns` sections short.
These strings end up in a table that we don't want to be bulky.
Try to keep these to one sentence/phrase where possible. If you need more
detail--even extremely common details, like "you need to free the returned
pointer"--put that information in the general Remarks section, where you
can be as verbose as you like.
(One exception for SDL: the return value almost always notes that on error,
you should call SDL_GetError() to get more information. The documentation
is so saturated with this that it's just the standard now.)
Convention at the moment is that pointer params that are permitted to
be NULL, which is somewhat uncommon, end with terse "May be NULL." sentence
at the end, and pointers that must be non-NULL (most of them) say nothing.
This is fine.
## Code examples go in the wiki.
We don't want the headers cluttered up with code examples. These live on the

View file

@ -101,7 +101,7 @@ don't want any shutdown code that might be sitting below this code
to actually run if main() were to continue on, since we're just
getting started.
Another option is to use SDL' main callbacks, which handle this for you
Another option is to use SDL's main callbacks, which handle this for you
without platform-specific code in your app. Please refer to
[the wiki](https://wiki.libsdl.org/SDL3/README-main-functions#main-callbacks-in-sdl3)
or `docs/README-main-functions.md` in the SDL source code.

View file

@ -25,14 +25,14 @@ Ubuntu 22.04+ can also add `libpipewire-0.3-dev libwayland-dev libdecor-0-dev li
Fedora 35, all available features enabled:
sudo yum install gcc git-core make cmake \
sudo dnf install gcc git-core make cmake \
alsa-lib-devel pulseaudio-libs-devel pipewire-devel \
libX11-devel libXext-devel libXrandr-devel libXcursor-devel libXfixes-devel \
libXi-devel libXScrnSaver-devel dbus-devel ibus-devel \
systemd-devel mesa-libGL-devel libxkbcommon-devel mesa-libGLES-devel \
mesa-libEGL-devel vulkan-devel wayland-devel wayland-protocols-devel \
libdrm-devel mesa-libgbm-devel libusb-devel libdecor-devel \
pipewire-jack-audio-connection-kit-devel \
libdrm-devel mesa-libgbm-devel libusb1-devel libdecor-devel \
pipewire-jack-audio-connection-kit-devel
Fedora 39+ can also add `liburing-devel` to that command line.

View file

@ -11,11 +11,17 @@ Credit to
## Building
To build SDL library for the PS2, make sure you have the latest PS2Dev status and run:
```bash
cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=$PS2DEV/ps2sdk/ps2dev.cmake
cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=$PS2DEV/share/ps2dev.cmake
cmake --build build
cmake --install build
```
## Hints
- `SDL_HINT_PS2_GS_WIDTH`: Width of the framebuffer. Defaults to 640.
- `SDL_HINT_PS2_GS_HEIGHT`: Height of the framebuffer. Defaults to 448.
- `SDL_HINT_PS2_GS_PROGRESSIVE`: Whether to use progressive, instead of interlaced. Defaults to 0.
- `SDL_HINT_PS2_GS_MODE`: Regional standard of the signal. "NTSC" (60hz), "PAL" (50hz) or "" (the console's region, default).
## Notes
If you trying to debug a SDL app through [ps2client](https://github.com/ps2dev/ps2client) you need to avoid the IOP reset, otherwise you will lose the connection with your computer.
So to avoid the reset of the IOP CPU, you need to call to the macro `SDL_PS2_SKIP_IOP_RESET();`.

View file

@ -149,9 +149,13 @@ add_sdl_example_executable(audio-multiple-streams SOURCES audio/04-multiple-stre
add_sdl_example_executable(audio-planar-data SOURCES audio/05-planar-data/planar-data.c)
add_sdl_example_executable(input-joystick-polling SOURCES input/01-joystick-polling/joystick-polling.c)
add_sdl_example_executable(input-joystick-events SOURCES input/02-joystick-events/joystick-events.c)
add_sdl_example_executable(input-gamepad-polling SOURCES input/03-gamepad-polling/gamepad-polling.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/gamepad_front.bmp)
add_sdl_example_executable(input-gamepad-events SOURCES input/04-gamepad-events/gamepad-events.c)
add_sdl_example_executable(camera-read-and-draw SOURCES camera/01-read-and-draw/read-and-draw.c)
add_sdl_example_executable(pen-drawing-lines SOURCES pen/01-drawing-lines/drawing-lines.c)
add_sdl_example_executable(asyncio-load-bitmaps SOURCES asyncio/01-load-bitmaps/load-bitmaps.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.bmp ${CMAKE_CURRENT_SOURCE_DIR}/../test/gamepad_front.bmp ${CMAKE_CURRENT_SOURCE_DIR}/../test/speaker.bmp ${CMAKE_CURRENT_SOURCE_DIR}/../test/icon2x.bmp)
add_sdl_example_executable(misc-power SOURCES misc/01-power/power.c)
add_sdl_example_executable(misc-clipboard SOURCES misc/02-clipboard/clipboard.c)
add_sdl_example_executable(demo-snake SOURCES demo/01-snake/snake.c)
add_sdl_example_executable(demo-woodeneye-008 SOURCES demo/02-woodeneye-008/woodeneye-008.c)
add_sdl_example_executable(demo-infinite-monkeys SOURCES demo/03-infinite-monkeys/infinite-monkeys.c)

View file

@ -65,3 +65,30 @@ If writing new examples, this is the skeleton code we start from, to keep
everything consistent. You can ignore it.
## How are the thumbnails/onmouseover media created?
(Since I have to figure this out every time.)
This is how Ryan is doing it currently.
- `rm -f frame*.bmp`
- Temporarily add `#include "../../save-rendering-to-bitmaps.h"` after any SDL
includes in the example program.
- Launch the example app, interact with it, let it run for a few seconds, quit.
- This will dump a "frameX.bmp" file for each frame rendered.
- Make a video in webp format from the bitmaps (this assumes the bitmaps were
stored at 60fps, you might have to tweak).
```bash
ffmpeg -framerate 60 -pattern_type glob -i 'frame*.bmp' -loop 0 -quality 40 -r 10 -frames:v 40 onmouseover.webp
```
You might need to start in the middle of the video, or mess with quality or
number of frames to generate, ymmv.
- Pick a frame for the thumbnail, make it a .png, and run that png through
pngquant for massive file size reduction without any obvious loss in quality:
```bash
convert frame00000.bmp cvt.png ; pngquant cvt.png --output thumbnail.png ; rm -f cvt.png
```

View file

@ -10,4 +10,5 @@ audio
camera
asyncio
pen
misc
demo

View file

@ -13,8 +13,8 @@
and knows how to map arbitrary buttons and such to look like an
Xbox/PlayStation/etc gamepad. This is easier, and better, for many games,
but isn't necessarily a good fit for complex apps and hardware. A flight
simulator, a realistic racing game, etc, might want this interface instead
of gamepads. */
simulator, a realistic racing game, etc, might want the joystick interface
instead of gamepads. */
/* SDL can handle multiple joysticks, but for simplicity, this program only
deals with the first stick it sees. */

View file

@ -13,8 +13,8 @@
and knows how to map arbitrary buttons and such to look like an
Xbox/PlayStation/etc gamepad. This is easier, and better, for many games,
but isn't necessarily a good fit for complex apps and hardware. A flight
simulator, a realistic racing game, etc, might want this interface instead
of gamepads. */
simulator, a realistic racing game, etc, might want the joystick interface
instead of gamepads. */
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
#include <SDL3/SDL.h>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 534 KiB

Before After
Before After

View file

@ -0,0 +1,11 @@
This example code looks for the current gamepad state once per frame,
and draws a visual representation of it. See 01-joystick-polling for the
equivalent example code for the lower-level joystick API.
Please note that on the web, gamepads don't show up until you interact with
them, so press a button to "connect" the controller.
Also note that on the web, gamepad triggers are treated as buttons (either
pressed or not) instead of axes (pressed 0 to 100 percent). This is a web
issue, not an SDL limitation.

View file

@ -0,0 +1,221 @@
/*
* This example code looks for the current gamepad state once per frame,
* and draws a visual representation of it. See 01-joystick-polling for the
* equivalent example code for the lower-level joystick API.
*
* This code is public domain. Feel free to use it for any purpose!
*/
/* Joysticks are low-level interfaces: there's something with a bunch of
buttons, axes and hats, in no understood order or position. This is
a flexible interface, but you'll need to build some sort of configuration
UI to let people tell you what button, etc, does what. On top of this
interface, SDL offers the "gamepad" API, which works with lots of devices,
and knows how to map arbitrary buttons and such to look like an
Xbox/PlayStation/etc gamepad. This is easier, and better, for many games,
but isn't necessarily a good fit for complex apps and hardware. A flight
simulator, a realistic racing game, etc, might want the joystick interface
instead of gamepads. */
/* SDL can handle multiple gamepads, but for simplicity, this program only
deals with the first gamepad it sees. */
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
/* We will use this renderer to draw into this window every frame. */
static SDL_Window *window = NULL;
static SDL_Renderer *renderer = NULL;
static SDL_Texture *texture = NULL;
static SDL_Gamepad *gamepad = NULL;
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
/* This function runs once at startup. */
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
{
char *bmp_path = NULL;
SDL_Surface *surface = NULL;
SDL_SetAppMetadata("Example Input Gamepad Polling", "1.0", "com.example.input-gamepad-polling");
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD)) {
SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
if (!SDL_CreateWindowAndRenderer("examples/input/gamepad-polling", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
if (!SDL_SetRenderLogicalPresentation(renderer, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_LOGICAL_PRESENTATION_STRETCH)) {
return SDL_APP_FAILURE;
}
/* Textures are pixel data that we upload to the video hardware for fast drawing. Lots of 2D
engines refer to these as "sprites." We'll do a static texture (upload once, draw many
times) with data from a bitmap file. */
/* SDL_Surface is pixel data the CPU can access. SDL_Texture is pixel data the GPU can access.
Load a .bmp into a surface, move it to a texture from there. */
SDL_asprintf(&bmp_path, "%sgamepad_front.bmp", SDL_GetBasePath()); /* allocate a string of the full file path */
surface = SDL_LoadBMP(bmp_path);
if (!surface) {
SDL_Log("Couldn't load bitmap: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
SDL_free(bmp_path); /* done with this, the file is loaded. */
texture = SDL_CreateTextureFromSurface(renderer, surface);
if (!texture) {
SDL_Log("Couldn't create static texture: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
SDL_DestroySurface(surface); /* done with this, the texture has a copy of the pixels now. */
return SDL_APP_CONTINUE; /* carry on with the program! */
}
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
{
if (event->type == SDL_EVENT_QUIT) {
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
} else if (event->type == SDL_EVENT_GAMEPAD_ADDED) {
/* this event is sent for each hotplugged gamepad, but also each already-connected gamepad during SDL_Init(). */
if (gamepad == NULL) { /* we don't have a stick yet and one was added, open it! */
gamepad = SDL_OpenGamepad(event->gdevice.which);
if (!gamepad) {
SDL_Log("Failed to open gamepad ID %u: %s", (unsigned int) event->gdevice.which, SDL_GetError());
}
}
} else if (event->type == SDL_EVENT_GAMEPAD_REMOVED) {
if (gamepad && (SDL_GetGamepadID(gamepad) == event->gdevice.which)) {
SDL_CloseGamepad(gamepad); /* our controller was unplugged. */
gamepad = NULL;
}
}
return SDL_APP_CONTINUE; /* carry on with the program! */
}
/* This function runs once per frame, and is the heart of the program. */
SDL_AppResult SDL_AppIterate(void *appstate)
{
const char *text = "Plug in a gamepad, please.";
static Uint64 leftthumblast = 0xFFFFFFFF;
static Uint64 rightthumblast = 0xFFFFFFFF;
const Uint64 now = SDL_GetTicks();
Sint16 axis_x, axis_y;
float x, y;
int i;
if (gamepad) { /* we have a stick opened? */
text = SDL_GetGamepadName(gamepad);
}
SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF); /* white */
SDL_RenderClear(renderer);
/* note that you can get input as events, instead of polling, which is
better since it won't miss button presses if the system is lagging,
but often times checking the current state per-frame is good enough,
and maybe better if you'd rather _drop_ inputs due to lag. */
if (gamepad) { /* we have a stick opened? */
/* where to draw the buttons */
const SDL_FRect buttons[] = {
{ 497, 266, 38, 38 }, /* SDL_GAMEPAD_BUTTON_SOUTH */
{ 550, 217, 38, 38 }, /* SDL_GAMEPAD_BUTTON_EAST */
{ 445, 221, 38, 38 }, /* SDL_GAMEPAD_BUTTON_WEST */
{ 499, 173, 38, 38 }, /* SDL_GAMEPAD_BUTTON_NORTH */
{ 235, 228, 32, 29 }, /* SDL_GAMEPAD_BUTTON_BACK */
{ 287, 195, 69, 69 }, /* SDL_GAMEPAD_BUTTON_GUIDE */
{ 377, 228, 32, 29 }, /* SDL_GAMEPAD_BUTTON_START */
{ 91, 234, 63, 63 }, /* SDL_GAMEPAD_BUTTON_LEFT_STICK */
{ 381, 354, 63, 63 }, /* SDL_GAMEPAD_BUTTON_RIGHT_STICK */
{ 74, 73, 102, 29 }, /* SDL_GAMEPAD_BUTTON_LEFT_SHOULDER */
{ 468, 73, 102, 29 }, /* SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER */
{ 207, 316, 32, 32 }, /* SDL_GAMEPAD_BUTTON_DPAD_UP */
{ 207, 384, 32, 32 }, /* SDL_GAMEPAD_BUTTON_DPAD_DOWN */
{ 173, 351, 32, 32 }, /* SDL_GAMEPAD_BUTTON_DPAD_LEFT */
{ 242, 351, 32, 32 }, /* SDL_GAMEPAD_BUTTON_DPAD_RIGHT */
{ 310, 286, 23, 27 }, /* SDL_GAMEPAD_BUTTON_MISC1 */
/* there are other buttons: paddles on the back of the gamepad, touchpads, etc, but this is good enough for now. */
};
SDL_RenderTexture(renderer, texture, NULL, NULL); /* draw the gamepad picture to the whole window. */
/* draw green boxes over buttons that are currently pressed. */
SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0xFF); /* green */
for (i = 0; i < SDL_arraysize(buttons); i++) {
if (SDL_GetGamepadButton(gamepad, (SDL_GamepadButton) i)) {
SDL_RenderFillRect(renderer, &buttons[i]);
}
}
SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0x00, 0xFF); /* yellow */
/* left thumb axis. */
axis_x = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFTX);
axis_y = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFTY);
if ((SDL_abs(axis_x) > 1000) || (SDL_abs(axis_y) > 1000)) { /* zero means centered, but it might be a little off zero... */
leftthumblast = now; /* keep drawing, we're still moving. */
}
if ((now - leftthumblast) < 500) { /* draw if there was movement in the last half-second. */
const SDL_FRect box = { 107 + ((axis_x / 32767.0f) * 30.0f), 252 + ((axis_y / 32767.0f) * 30.0f), 30, 30 };
SDL_RenderFillRect(renderer, &box);
}
/* right thumb axis. */
axis_x = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTX);
axis_y = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTY);
if ((SDL_abs(axis_x) > 1000) || (SDL_abs(axis_y) > 1000)) { /* zero means centered, but it might be a little off zero... */
rightthumblast = now; /* keep drawing, we're still moving. */
}
if ((now - rightthumblast) < 500) { /* draw if there was movement in the last half-second. */
const SDL_FRect box = { 397 + ((axis_x / 32767.0f) * 30.0f), 370 + ((axis_y / 32767.0f) * 30.0f), 30, 30 };
SDL_RenderFillRect(renderer, &box);
}
/* left trigger. */
axis_y = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFT_TRIGGER);
if (axis_y > 1000) { /* zero means unpressed, but it might be a little off zero... */
const float height = ((axis_y / 32767.0f) * 65.0f);
const SDL_FRect box = { 127, 1 + (65.0f - height), 37, height };
SDL_RenderFillRect(renderer, &box);
}
/* right trigger. */
axis_y = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER);
if (axis_y > 1000) { /* zero means unpressed, but it might be a little off zero... */
const float height = ((axis_y / 32767.0f) * 65.0f);
const SDL_FRect box = { 481, 1 + (65.0f - height), 37, height };
SDL_RenderFillRect(renderer, &box);
}
}
x = (((float) WINDOW_WIDTH) - (SDL_strlen(text) * SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE)) / 2.0f;
if (gamepad) {
y = (float) (WINDOW_HEIGHT - (SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE + 2));
} else {
y = (((float) WINDOW_HEIGHT) - SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE) / 2.0f;
}
SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0xFF, 0xFF); /* blue */
SDL_RenderDebugText(renderer, x, y, text);
SDL_RenderPresent(renderer);
return SDL_APP_CONTINUE; /* carry on with the program! */
}
/* This function runs once at shutdown. */
void SDL_AppQuit(void *appstate, SDL_AppResult result)
{
SDL_DestroyTexture(texture);
SDL_CloseGamepad(gamepad);
/* SDL will clean up the window/renderer for us. */
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View file

@ -0,0 +1,2 @@
This example code looks for gamepad input in the event handler, and
reports any changes as a flood of info.

View file

@ -0,0 +1,212 @@
/*
* This example code looks for gamepad input in the event handler, and
* reports any changes as a flood of info.
*
* This code is public domain. Feel free to use it for any purpose!
*/
/* Joysticks are low-level interfaces: there's something with a bunch of
buttons, axes and hats, in no understood order or position. This is
a flexible interface, but you'll need to build some sort of configuration
UI to let people tell you what button, etc, does what. On top of this
interface, SDL offers the "gamepad" API, which works with lots of devices,
and knows how to map arbitrary buttons and such to look like an
Xbox/PlayStation/etc gamepad. This is easier, and better, for many games,
but isn't necessarily a good fit for complex apps and hardware. A flight
simulator, a realistic racing game, etc, might want the joystick interface
instead of gamepads. */
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
/* We will use this renderer to draw into this window every frame. */
static SDL_Window *window = NULL;
static SDL_Renderer *renderer = NULL;
static SDL_Color colors[64];
#define MOTION_EVENT_COOLDOWN 40
typedef struct EventMessage
{
char *str;
SDL_Color color;
Uint64 start_ticks;
struct EventMessage *next;
} EventMessage;
static EventMessage messages;
static EventMessage *messages_tail = &messages;
static const char *battery_state_string(SDL_PowerState state)
{
switch (state) {
case SDL_POWERSTATE_ERROR: return "ERROR";
case SDL_POWERSTATE_UNKNOWN: return "UNKNOWN";
case SDL_POWERSTATE_ON_BATTERY: return "ON BATTERY";
case SDL_POWERSTATE_NO_BATTERY: return "NO BATTERY";
case SDL_POWERSTATE_CHARGING: return "CHARGING";
case SDL_POWERSTATE_CHARGED: return "CHARGED";
default: break;
}
return "UNKNOWN";
}
static void add_message(SDL_JoystickID jid, const char *fmt, ...)
{
const SDL_Color *color = &colors[((size_t) jid) % SDL_arraysize(colors)];
EventMessage *msg = NULL;
char *str = NULL;
va_list ap;
msg = (EventMessage *) SDL_calloc(1, sizeof (*msg));
if (!msg) {
return; // oh well.
}
va_start(ap, fmt);
SDL_vasprintf(&str, fmt, ap);
va_end(ap);
if (!str) {
SDL_free(msg);
return; // oh well.
}
msg->str = str;
SDL_copyp(&msg->color, color);
msg->start_ticks = SDL_GetTicks();
msg->next = NULL;
messages_tail->next = msg;
messages_tail = msg;
}
/* This function runs once at startup. */
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
{
int i;
SDL_SetAppMetadata("Example Input Gamepad Events", "1.0", "com.example.input-gamepad-events");
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD)) {
SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
if (!SDL_CreateWindowAndRenderer("examples/input/gamepad-events", 640, 480, 0, &window, &renderer)) {
SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
colors[0].r = colors[0].g = colors[0].b = colors[0].a = 255;
for (i = 1; i < SDL_arraysize(colors); i++) {
colors[i].r = SDL_rand(255);
colors[i].g = SDL_rand(255);
colors[i].b = SDL_rand(255);
colors[i].a = 255;
}
add_message(0, "Please plug in a gamepad.");
return SDL_APP_CONTINUE; /* carry on with the program! */
}
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
{
if (event->type == SDL_EVENT_QUIT) {
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
} else if (event->type == SDL_EVENT_GAMEPAD_ADDED) {
/* this event is sent for each hotplugged stick, but also each already-connected gamepad during SDL_Init(). */
const SDL_JoystickID which = event->gdevice.which;
SDL_Gamepad *gamepad = SDL_OpenGamepad(which);
if (!gamepad) {
add_message(which, "Gamepad #%u add, but not opened: %s", (unsigned int) which, SDL_GetError());
} else {
char *mapping = SDL_GetGamepadMapping(gamepad);
add_message(which, "Gamepad #%u ('%s') added", (unsigned int) which, SDL_GetGamepadName(gamepad));
if (mapping) {
add_message(which, "Gamepad #%u mapping: %s", (unsigned int) which, mapping);
SDL_free(mapping);
}
}
} else if (event->type == SDL_EVENT_GAMEPAD_REMOVED) {
const SDL_JoystickID which = event->gdevice.which;
SDL_Gamepad *gamepad = SDL_GetGamepadFromID(which);
if (gamepad) {
SDL_CloseGamepad(gamepad); /* the gamepad was unplugged. */
}
add_message(which, "Gamepad #%u removed", (unsigned int) which);
} else if (event->type == SDL_EVENT_GAMEPAD_AXIS_MOTION) {
static Uint64 axis_motion_cooldown_time = 0; /* these are spammy, only show every X milliseconds. */
const Uint64 now = SDL_GetTicks();
if (now >= axis_motion_cooldown_time) {
const SDL_JoystickID which = event->gaxis.which;
axis_motion_cooldown_time = now + MOTION_EVENT_COOLDOWN;
add_message(which, "Gamepad #%u axis %s -> %d", (unsigned int) which, SDL_GetGamepadStringForAxis((SDL_GamepadAxis) event->gaxis.axis), (int) event->gaxis.value);
}
} else if ((event->type == SDL_EVENT_GAMEPAD_BUTTON_UP) || (event->type == SDL_EVENT_GAMEPAD_BUTTON_DOWN)) {
const SDL_JoystickID which = event->gbutton.which;
add_message(which, "Gamepad #%u button %s -> %s", (unsigned int) which, SDL_GetGamepadStringForButton((SDL_GamepadButton) event->gbutton.button), event->gbutton.down ? "PRESSED" : "RELEASED");
} else if (event->type == SDL_EVENT_JOYSTICK_BATTERY_UPDATED) {
const SDL_JoystickID which = event->jbattery.which;
if (SDL_IsGamepad(which)) { /* this is only reported for joysticks, so make sure this joystick is _actually_ a gamepad. */
add_message(which, "Gamepad #%u battery -> %s - %d%%", (unsigned int) which, battery_state_string(event->jbattery.state), event->jbattery.percent);
}
}
return SDL_APP_CONTINUE; /* carry on with the program! */
}
/* This function runs once per frame, and is the heart of the program. */
SDL_AppResult SDL_AppIterate(void *appstate)
{
const Uint64 now = SDL_GetTicks();
const float msg_lifetime = 3500.0f; /* milliseconds a message lives for. */
EventMessage *msg = messages.next;
float prev_y = 0.0f;
int winw = 640, winh = 480;
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_GetWindowSize(window, &winw, &winh);
while (msg) {
float x, y;
const float life_percent = ((float) (now - msg->start_ticks)) / msg_lifetime;
if (life_percent >= 1.0f) { /* msg is done. */
messages.next = msg->next;
if (messages_tail == msg) {
messages_tail = &messages;
}
SDL_free(msg->str);
SDL_free(msg);
msg = messages.next;
continue;
}
x = (((float) winw) - (SDL_strlen(msg->str) * SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE)) / 2.0f;
y = ((float) winh) * life_percent;
if ((prev_y != 0.0f) && ((prev_y - y) < ((float) SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE))) {
msg->start_ticks = now;
break; // wait for the previous message to tick up a little.
}
SDL_SetRenderDrawColor(renderer, msg->color.r, msg->color.g, msg->color.b, (Uint8) (((float) msg->color.a) * (1.0f - life_percent)));
SDL_RenderDebugText(renderer, x, y, msg->str);
prev_y = y;
msg = msg->next;
}
SDL_RenderPresent(renderer);
return SDL_APP_CONTINUE; /* carry on with the program! */
}
/* This function runs once at shutdown. */
void SDL_AppQuit(void *appstate, SDL_AppResult result)
{
SDL_Quit();
/* SDL will clean up the window/renderer for us. We let the gamepads leak. */
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 435 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -0,0 +1,4 @@
This example code reports power status (plugged in, battery level, etc).
Note that only Chrome-based browsers support this API currently. Firefox and
Safari will report this as unknown, but this may change later!

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View file

@ -0,0 +1,154 @@
/*
* This example code reports power status (plugged in, battery level, etc).
*
* This code is public domain. Feel free to use it for any purpose!
*/
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
/* We will use this renderer to draw into this window every frame. */
static SDL_Window *window = NULL;
static SDL_Renderer *renderer = NULL;
/* This function runs once at startup. */
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
{
SDL_SetAppMetadata("Example Misc Power", "1.0", "com.example.misc-power");
if (!SDL_Init(SDL_INIT_VIDEO)) {
SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
if (!SDL_CreateWindowAndRenderer("examples/misc/power", 640, 480, 0, &window, &renderer)) {
SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
return SDL_APP_CONTINUE; /* carry on with the program! */
}
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
{
if (event->type == SDL_EVENT_QUIT) {
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
}
return SDL_APP_CONTINUE; /* carry on with the program! */
}
/* This function runs once per frame, and is the heart of the program. */
SDL_AppResult SDL_AppIterate(void *appstate)
{
const SDL_FRect frame = { 100, 200, 440, 80 }; /* the percentage bar dimensions. */
/* Query for battery info */
int seconds = 0, percent = 0;
const SDL_PowerState state = SDL_GetPowerInfo(&seconds, &percent);
/* We set up different drawing details for each power state, then
run it all through the same drawing code. */
int clearr = 0, clearg = 0, clearb = 0; /* clear window to this color. */
int textr = 255, textg = 255, textb = 255; /* draw messages in this color. */
int framer = 255, frameg = 255, frameb = 255; /* draw a percentage bar frame in this color. */
int barr = 0, barg = 0, barb = 0; /* draw a percentage bar in this color. */
const char *msg = NULL;
const char *msg2 = NULL;
switch (state) {
case SDL_POWERSTATE_ERROR:
msg2 = "ERROR GETTING POWER STATE";
msg = SDL_GetError();
clearr = 255; /* red background */
break;
default: /* in case this does something unexpected later, treat it as unknown. */
case SDL_POWERSTATE_UNKNOWN:
msg = "Power state is unknown.";
clearr = clearb = clearg = 50; /* grey background */
break;
case SDL_POWERSTATE_ON_BATTERY:
msg = "Running on battery.";
barr = 255; /* draw in red */
break;
case SDL_POWERSTATE_NO_BATTERY:
msg = "Plugged in, no battery available.";
clearg = 50; /* green background */
break;
case SDL_POWERSTATE_CHARGING:
msg = "Charging.";
barb = barg = 255; /* draw in cyan */
break;
case SDL_POWERSTATE_CHARGED:
msg = "Charged.";
barg = 255; /* draw in green */
break;
}
SDL_SetRenderDrawColor(renderer, clearr, clearg, clearb, 255);
SDL_RenderClear(renderer);
if (percent >= 0) {
float x, y;
SDL_FRect pctrect;
char remainstr[64];
char msgbuf[128];
SDL_copyp(&pctrect, &frame);
pctrect.w *= percent / 100.0f;
if (seconds < 0) {
SDL_strlcpy(remainstr, "unknown time", sizeof (remainstr));
} else {
int hours, minutes;
hours = seconds / (60 * 60);
seconds -= hours * (60 * 60);
minutes = seconds / 60;
seconds -= minutes * 60;
SDL_snprintf(remainstr, sizeof (remainstr), "%02d:%02d:%02d", hours, minutes, seconds);
}
SDL_snprintf(msgbuf, sizeof (msgbuf), "Battery: %3d percent, %s remaining", percent, remainstr);
x = frame.x + ((frame.w - (SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * SDL_strlen(msgbuf))) / 2.0f);
y = frame.y + frame.h + SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE;
SDL_SetRenderDrawColor(renderer, barr, barg, barb, 255); /* draw percent bar. */
SDL_RenderFillRect(renderer, &pctrect);
SDL_SetRenderDrawColor(renderer, framer, frameg, frameb, 255); /* draw frame on top of bar. */
SDL_RenderRect(renderer, &frame);
SDL_SetRenderDrawColor(renderer, textr, textg, textb, 255);
SDL_RenderDebugText(renderer, x, y, msgbuf); /* draw text about battery level */
}
if (msg) {
const float x = frame.x + ((frame.w - (SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * SDL_strlen(msg))) / 2.0f);
const float y = frame.y - (SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * 2);
SDL_SetRenderDrawColor(renderer, textr, textg, textb, 255);
SDL_RenderDebugText(renderer, x, y, msg);
}
if (msg2) {
const float x = frame.x + ((frame.w - (SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * SDL_strlen(msg2))) / 2.0f);
const float y = frame.y - (SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * 4);
SDL_SetRenderDrawColor(renderer, textr, textg, textb, 255);
SDL_RenderDebugText(renderer, x, y, msg2);
}
/* put the new rendering on the screen. */
SDL_RenderPresent(renderer);
return SDL_APP_CONTINUE; /* carry on with the program! */
}
/* This function runs once at shutdown. */
void SDL_AppQuit(void *appstate, SDL_AppResult result)
{
/* SDL will clean up the window/renderer for us. */
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 622 B

View file

@ -0,0 +1,6 @@
This example code lets the user copy and paste with the system clipboard.
This only handles text, but SDL supports other data types, too.
Note that only Chrome-based browsers support this API currently. This uses a
new Javascript API, so hopefully this will be available everywhere soon!

View file

@ -0,0 +1,233 @@
/*
* This example code lets the user copy and paste with the system clipboard.
*
* This only handles text, but SDL supports other data types, too.
*
* This code is public domain. Feel free to use it for any purpose!
*/
#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
/* We will use this renderer to draw into this window every frame. */
static SDL_Window *window = NULL;
static SDL_Renderer *renderer = NULL;
static const char *copybuttonstr = "Click here to copy!";
static const char *pastebuttonstr = "Click here to paste!";
static SDL_FRect currenttimerect;
static SDL_FRect copybuttonrect;
static SDL_FRect pastetextrect;
static SDL_FRect pastebuttonrect;
static bool copy_pressed = false;
static bool paste_pressed = false;
static char current_time[64];
static char *pasted_str = NULL;
static void CalculateCurrentTimeString(void)
{
SDL_Time ticks = 0;
SDL_DateTime dt;
if (!SDL_GetCurrentTime(&ticks) || !SDL_TimeToDateTime(ticks, &dt, true)) {
SDL_snprintf(current_time, sizeof (current_time), "(Don't know the current time, sorry.)");
} else {
static const char *month[12] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
static const char *day[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
SDL_snprintf(current_time, sizeof (current_time), "%s, %s %d, %d %02d:%02d:%02d", day[dt.day_of_week], month[dt.month-1], dt.day, dt.year, dt.hour, dt.minute, dt.second);
}
}
/* This function runs once at startup. */
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
{
SDL_SetAppMetadata("Example Misc Clipboard", "1.0", "com.example.misc-clipboard");
if (!SDL_Init(SDL_INIT_VIDEO)) {
SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
if (!SDL_CreateWindowAndRenderer("examples/misc/clipboard", 640, 480, 0, &window, &renderer)) {
SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
CalculateCurrentTimeString();
/* set up the locations where we'll draw stuff. */
currenttimerect.x = 30;
currenttimerect.y = 10;
currenttimerect.w = 390;
currenttimerect.h = SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE + 10;
copybuttonrect.x = currenttimerect.x + currenttimerect.w + 30;
copybuttonrect.y = currenttimerect.y;
copybuttonrect.w = (float) ((SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * SDL_strlen(copybuttonstr)) + 10);
copybuttonrect.h = currenttimerect.h;
pastetextrect.x = 10;
pastetextrect.y = currenttimerect.y + currenttimerect.h + 10;
pastetextrect.w = 620;
pastetextrect.h = ((480 - pastetextrect.y) - copybuttonrect.h) - 20;
pastebuttonrect.w = (float) ((SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * SDL_strlen(pastebuttonstr)) + 10);
pastebuttonrect.x = (640 - pastebuttonrect.w) / 2.0f;
pastebuttonrect.y = pastetextrect.y + pastetextrect.h + 10;
pastebuttonrect.h = copybuttonrect.h;
return SDL_APP_CONTINUE; /* carry on with the program! */
}
/* This function runs when a new event (mouse input, keypresses, etc) occurs. */
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
{
if (event->type == SDL_EVENT_QUIT) {
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
} else if (event->type == SDL_EVENT_MOUSE_BUTTON_DOWN) {
if (event->button.button == SDL_BUTTON_LEFT) {
const SDL_FPoint p = { event->button.x, event->button.y };
copy_pressed = SDL_PointInRectFloat(&p, &copybuttonrect);
paste_pressed = SDL_PointInRectFloat(&p, &pastebuttonrect);
}
} else if (event->type == SDL_EVENT_MOUSE_BUTTON_UP) {
if (event->button.button == SDL_BUTTON_LEFT) {
const SDL_FPoint p = { event->button.x, event->button.y };
if (copy_pressed && SDL_PointInRectFloat(&p, &copybuttonrect)) {
SDL_SetClipboardText(current_time);
} else if (paste_pressed && SDL_PointInRectFloat(&p, &pastebuttonrect)) {
SDL_free(pasted_str);
pasted_str = SDL_GetClipboardText();
}
copy_pressed = paste_pressed = false;
}
}
return SDL_APP_CONTINUE; /* carry on with the program! */
}
static void RenderPastedText(void)
{
char *str = pasted_str;
if (str) {
float x = pastetextrect.x + 5;
float y = pastetextrect.y + 5;
const float w = pastetextrect.w - 10;
const float h = pastetextrect.h;
const size_t max_chars_per_line = (size_t) (w / SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE);
char *newline;
size_t slen;
char ch;
/* this doesn't wordwrap, or deal with Unicode....this is just a simple example app! */
while ((newline = SDL_strchr(str, '\n')) != NULL) {
const bool ignore_cr = ((newline > str) && (newline[-1] == '\r'));
if (ignore_cr) {
newline[-1] = '\0';
}
*newline = '\0';
slen = SDL_strlen(str); /* length to end of line. */
slen = SDL_min(slen, max_chars_per_line);
ch = str[slen];
str[slen] = '\0';
SDL_RenderDebugText(renderer, x, y, str);
str[slen] = ch;
if (ignore_cr) {
newline[-1] = '\r';
}
*newline = '\n';
str = newline + 1;
y += (SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE + 2);
if ((h - y) < SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE) {
break; // no space for another line, stop here.
}
}
/* last text after newline, if there's room. */
if ((h - y) >= SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE) {
slen = SDL_strlen(str); /* length to end of line. */
slen = SDL_min(slen, max_chars_per_line);
ch = str[slen];
str[slen] = '\0';
SDL_RenderDebugText(renderer, x, y, str);
str[slen] = ch;
}
}
}
/* This function runs once per frame, and is the heart of the program. */
SDL_AppResult SDL_AppIterate(void *appstate)
{
float x, y;
CalculateCurrentTimeString();
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); /* black */
SDL_RenderClear(renderer);
/* draw a frame around the current time. */
SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
SDL_RenderFillRect(renderer, &currenttimerect);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderRect(renderer, &currenttimerect);
/* draw the current time inside the frame. */
x = currenttimerect.x + ((currenttimerect.w - (SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * SDL_strlen(current_time))) / 2.0f);
y = currenttimerect.y + 5;
SDL_SetRenderDrawColor(renderer, 255, 255, 0, 255);
SDL_RenderDebugText(renderer, x, y, current_time);
/* draw a frame for the "copy the current time to the clipboard" button. */
if (copy_pressed) {
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
} else {
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
}
SDL_RenderFillRect(renderer, &copybuttonrect);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderRect(renderer, &copybuttonrect);
/* draw the "copy this text" button string. */
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderDebugText(renderer, copybuttonrect.x + 5, copybuttonrect.y + 5, copybuttonstr);
/* draw a frame for the pasted text area. */
SDL_SetRenderDrawColor(renderer, 0, 53, 25, 255);
SDL_RenderFillRect(renderer, &pastetextrect);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderRect(renderer, &pastetextrect);
/* draw pasted text. */
SDL_SetRenderDrawColor(renderer, 0, 219, 107, 255);
RenderPastedText();
/* draw a frame for the "paste from the clipboard" button. */
if (paste_pressed) {
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
} else {
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
}
SDL_RenderFillRect(renderer, &pastebuttonrect);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderRect(renderer, &pastebuttonrect);
/* draw the "paste some text" button string. */
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderDebugText(renderer, pastebuttonrect.x + 5, pastebuttonrect.y + 5, pastebuttonstr);
/* put the new rendering on the screen. */
SDL_RenderPresent(renderer);
return SDL_APP_CONTINUE; /* carry on with the program! */
}
/* This function runs once at shutdown. */
void SDL_AppQuit(void *appstate, SDL_AppResult result)
{
SDL_free(pasted_str);
/* SDL will clean up the window/renderer for us. */
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -0,0 +1 @@
Various examples from smaller subsystems

View file

@ -93,20 +93,20 @@ SDL_AppResult SDL_AppIterate(void *appstate)
/* Set a new clipping rectangle position */
cliprect_position.x += distance * cliprect_direction.x;
if (cliprect_position.x < 0.0f) {
cliprect_position.x = 0.0f;
if (cliprect_position.x < -CLIPRECT_SIZE) {
cliprect_position.x = -CLIPRECT_SIZE;
cliprect_direction.x = 1.0f;
} else if (cliprect_position.x >= (WINDOW_WIDTH - CLIPRECT_SIZE)) {
cliprect_position.x = (WINDOW_WIDTH - CLIPRECT_SIZE) - 1;
} else if (cliprect_position.x >= WINDOW_WIDTH) {
cliprect_position.x = WINDOW_WIDTH - 1;
cliprect_direction.x = -1.0f;
}
cliprect_position.y += distance * cliprect_direction.y;
if (cliprect_position.y < 0.0f) {
cliprect_position.y = 0.0f;
if (cliprect_position.y < -CLIPRECT_SIZE) {
cliprect_position.y = -CLIPRECT_SIZE;
cliprect_direction.y = 1.0f;
} else if (cliprect_position.y >= (WINDOW_HEIGHT - CLIPRECT_SIZE)) {
cliprect_position.y = (WINDOW_HEIGHT - CLIPRECT_SIZE) - 1;
} else if (cliprect_position.y >= WINDOW_HEIGHT) {
cliprect_position.y = WINDOW_HEIGHT - 1;
cliprect_direction.y = -1.0f;
}
SDL_SetRenderClipRect(renderer, &cliprect);

View file

@ -0,0 +1,49 @@
/*
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.
*/
/*
This is for generating thumbnails and videos of examples. Just include it
temporarily and let it override SDL_RenderPresent, etc, and it'll dump each
frame rendered to a new .bmp file.
*/
static bool SAVERENDERING_SDL_RenderPresent(SDL_Renderer *renderer)
{
static unsigned int framenum = 0;
SDL_Surface *surface = SDL_RenderReadPixels(renderer, NULL);
if (!surface) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Failed to read pixels for frame #%u! (%s)", framenum, SDL_GetError());
} else {
char fname[64];
SDL_snprintf(fname, sizeof (fname), "frame%05u.bmp", framenum);
if (!SDL_SaveBMP(surface, fname)) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Failed to save bmp for frame #%u! (%s)", framenum, SDL_GetError());
}
SDL_DestroySurface(surface);
}
framenum++;
return SDL_RenderPresent(renderer);
}
#define SDL_RenderPresent SAVERENDERING_SDL_RenderPresent

View file

@ -6,6 +6,9 @@
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>@project_name@ Examples: @category_description@</title>
<link rel="icon" href="/@project_name@/thumbnail.png" type="image/png" />
@preload_images_html@
<link
rel="stylesheet"
type="text/css"
@ -21,7 +24,6 @@
<meta property="og:title" content="@project_name@ Examples: @category_description@">
<meta property="og:description" content="@project_name@ Examples: @category_description@">
<meta property="og:image" content="@preview_image@" />
</head>
<body>
<header>
@ -31,7 +33,7 @@
<nav class="breadcrumb">
<ul>
<li><a href="/@project_name@/">@project_name@</a></li>
<li><a href="/@project_name@/@category_name@">@category_name@</a></li>
<li><a href="/@project_name@/@category_name@/">@category_name@</a></li>
</ul>
</nav>
<h1>@project_name@ examples: @category_description@</h1>

View file

@ -6,6 +6,9 @@
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>@project_name@ Examples</title>
<link rel="icon" href="/@project_name@/thumbnail.png" type="image/png" />
@preload_images_html@
<link
rel="stylesheet"
type="text/css"
@ -30,7 +33,7 @@
<main>
<nav class="breadcrumb">
<ul>
<li><a href="/@project_name@">@project_name@</a></li>
<li><a href="/@project_name@/">@project_name@</a></li>
</ul>
</nav>
<h1>@project_name@ examples</h1>

View file

@ -9,7 +9,7 @@
<meta property="og:type" content="website">
<meta property="og:title" content="@project_name@ Example: @category_name@/@example_name@">
<meta property="og:description" content="@description@">
<meta property="og:description" content="@short_description@">
<meta property="og:image" content="@preview_image@" />
<link rel="stylesheet" type="text/css" href="/@project_name@/examples.css" />
@ -202,9 +202,9 @@
<div id="content">
<nav class="breadcrumb">
<ul>
<li><a href="/@project_name@">@project_name@</a></li>
<li><a href="/@project_name@/@category_name@">@category_name@</a></li>
<li><a href="/@project_name@/@category_name@/@example_name@">@example_name@</a></li>
<li><a href="/@project_name@/">@project_name@</a></li>
<li><a href="/@project_name@/@category_name@/">@category_name@</a></li>
<li><a href="/@project_name@/@category_name@/@example_name@/">@example_name@</a></li>
</ul>
</nav>
<hr/>

View file

@ -132,9 +132,6 @@ extern "C" {
#define SDL_TriggerBreakpoint() __debugbreak()
#elif defined(_MSC_VER) && defined(_M_IX86)
#define SDL_TriggerBreakpoint() { _asm { int 0x03 } }
#elif defined(ANDROID) || defined(__SYMBIAN32__)
#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)

View file

@ -360,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
@ -372,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.
*

View file

@ -46,7 +46,7 @@
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
/* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version,
so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */
#ifdef __clang__
#if defined(__clang__) && !SDL_HAS_BUILTIN(_m_prefetch)
#ifndef __PRFCHWINTRIN_H
#define __PRFCHWINTRIN_H
static __inline__ void __attribute__((__always_inline__, __nodebug__))

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
@ -1396,7 +1396,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
@ -1409,7 +1412,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.

View file

@ -424,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);
@ -438,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);
@ -450,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
@ -467,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
@ -487,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
@ -499,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
@ -514,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
@ -528,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
@ -544,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
@ -560,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
@ -575,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
@ -591,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
@ -608,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
@ -625,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
@ -642,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
@ -657,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
@ -673,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
@ -690,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
@ -704,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
@ -719,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);
@ -729,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
@ -759,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);
@ -777,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);
@ -789,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
@ -803,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
@ -816,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
@ -829,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
@ -843,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
@ -858,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
@ -872,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
@ -886,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
@ -900,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
@ -914,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);
@ -926,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);
@ -939,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);
@ -951,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);
@ -971,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);
@ -983,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);
@ -1003,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);
@ -1015,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
@ -1030,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
@ -1046,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);
@ -1057,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);
@ -1073,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
@ -1087,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
@ -1109,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
@ -1123,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
@ -1139,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
@ -1165,6 +1261,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GamepadHasAxis(SDL_Gamepad *gamepad, SDL_Ga
* \param axis an axis index (one of the SDL_GamepadAxis values).
* \returns axis state.
*
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_GamepadHasAxis
@ -1184,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
@ -1198,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
@ -1214,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
@ -1227,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
@ -1241,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
@ -1254,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
@ -1266,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
@ -1280,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
@ -1303,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
@ -1316,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
@ -1333,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
@ -1347,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
@ -1360,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);
@ -1377,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);
@ -1399,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);
@ -1425,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
@ -1447,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);
@ -1460,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);
@ -1470,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
@ -1484,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
@ -1497,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

@ -230,6 +230,15 @@
* - `drawIndirectFirstInstance`
* - `sampleRateShading`
*
* You can remove some of these requirements to increase compatibility with
* Android devices by using these properties when creating the GPU device with
* SDL_CreateGPUDeviceWithProperties():
*
* - SDL_PROP_GPU_DEVICE_CREATE_FEATURE_CLIP_DISTANCE_BOOLEAN
* - SDL_PROP_GPU_DEVICE_CREATE_FEATURE_DEPTH_CLAMPING_BOOLEAN
* - SDL_PROP_GPU_DEVICE_CREATE_FEATURE_INDIRECT_DRAW_FIRST_INSTANCE_BOOLEAN
* - SDL_PROP_GPU_DEVICE_CREATE_FEATURE_ANISOTROPY_BOOLEAN
*
* ### D3D12
*
* SDL driver name: "direct3d12"
@ -238,6 +247,12 @@
* (GDK). Requires a GPU that supports DirectX 12 Feature Level 11_0 and
* Resource Binding Tier 2 or above.
*
* You can remove the Tier 2 resource binding requirement to support Intel
* Haswell and Broadwell GPUs by using this property when creating the GPU
* device with SDL_CreateGPUDeviceWithProperties():
*
* - SDL_PROP_GPU_DEVICE_CREATE_D3D12_ALLOW_FEWER_RESOURCE_SLOTS_BOOLEAN
*
* ### Metal
*
* SDL driver name: "metal"
@ -2055,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
@ -2069,8 +2087,8 @@ typedef struct SDL_GPUDepthStencilTargetInfo
SDL_GPUStoreOp stencil_store_op; /**< What is done with the stencil results of the render pass. */
bool cycle; /**< true cycles the texture if the texture is bound and any load ops are not LOAD */
Uint8 clear_stencil; /**< The value to clear the stencil component to at the beginning of the render pass. Ignored if SDL_GPU_LOADOP_CLEAR is not used. */
Uint8 padding1;
Uint8 padding2;
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;
/**
@ -2239,6 +2257,27 @@ extern SDL_DECLSPEC SDL_GPUDevice * SDLCALL SDL_CreateGPUDevice(
* 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:
*
@ -2259,25 +2298,14 @@ extern SDL_DECLSPEC SDL_GPUDevice * SDLCALL SDL_CreateGPUDevice(
*
* - `SDL_PROP_GPU_DEVICE_CREATE_D3D12_SEMANTIC_NAME_STRING`: the prefix to
* use for all vertex semantics, default is "TEXCOORD".
*
* With the Vulkan renderer:
*
* - `SDL_PROP_GPU_DEVICE_CREATE_VULKAN_SHADERCLIPDISTANCE_BOOLEAN`: Enable
* 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. Defaults to true.
* - `SDL_PROP_GPU_DEVICE_CREATE_VULKAN_DEPTHCLAMP_BOOLEAN`: Enable device
* feature depthClamp. If disabled, there is no depth clamp support and
* enable_depth_clip in SDL_GPURasterizerState must always be set to true.
* Defaults to true.
* - `SDL_PROP_GPU_DEVICE_CREATE_VULKAN_DRAWINDIRECTFIRST_BOOLEAN`: Enable
* device feature drawIndirectFirstInstance. If disabled, the argument
* first_instance of SDL_GPUIndirectDrawCommand must be set to zero.
* Defaults to true.
* - `SDL_PROP_GPU_DEVICE_CREATE_VULKAN_SAMPLERANISOTROPY_BOOLEAN`: Enable
* device feature samplerAnisotropy. If disabled, enable_anisotropy of
* SDL_GPUSamplerCreateInfo must be set to false. Defaults to true.
* - `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.
*
* \param props the properties to use.
* \returns a GPU context on success or NULL on failure; call SDL_GetError()
@ -2293,21 +2321,22 @@ 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_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_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_VULKAN_SHADERCLIPDISTANCE_BOOLEAN "SDL.gpu.device.create.vulkan.shaderclipdistance"
#define SDL_PROP_GPU_DEVICE_CREATE_VULKAN_DEPTHCLAMP_BOOLEAN "SDL.gpu.device.create.vulkan.depthclamp"
#define SDL_PROP_GPU_DEVICE_CREATE_VULKAN_DRAWINDIRECTFIRST_BOOLEAN "SDL.gpu.device.create.vulkan.drawindirectfirstinstance"
#define SDL_PROP_GPU_DEVICE_CREATE_VULKAN_SAMPLERANISOTROPY_BOOLEAN "SDL.gpu.device.create.vulkan.sampleranisotropy"
#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"
/**
* Destroys a GPU context previously returned by SDL_CreateGPUDevice.
@ -4420,6 +4449,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
/**
@ -4460,8 +4512,3 @@ extern SDL_DECLSPEC void SDLCALL SDL_GDKResumeGPU(SDL_GPUDevice *device);
#include <SDL3/SDL_close_code.h>
#endif /* SDL_gpu_h_ */

View file

@ -685,6 +685,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.
@ -738,6 +753,28 @@ extern "C" {
*/
#define SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT "SDL_EMSCRIPTEN_KEYBOARD_ELEMENT"
/**
* Dictate that newly-created windows will fill the whole browser window.
*
* 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. 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 should be set before creating a window.
*
* \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.
@ -1760,6 +1797,18 @@ extern "C" {
*/
#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.
@ -2227,8 +2276,8 @@ extern "C" {
*
* The variable can be set to the following values:
*
* - "0": WGI is not used.
* - "1": WGI is used. (default)
* - "0": WGI is not used. (default)
* - "1": WGI is used.
*
* This hint should be set before SDL is initialized.
*
@ -2410,6 +2459,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.
@ -2598,7 +2652,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
@ -2964,6 +3018,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.
*
@ -3146,6 +3218,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.
*
@ -4194,7 +4297,7 @@ extern "C" {
*
* \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.
@ -4239,7 +4342,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
@ -4535,19 +4638,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.
@ -4623,8 +4721,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

@ -182,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);
@ -189,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);
@ -198,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
@ -213,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
@ -229,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
@ -245,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
@ -260,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
@ -276,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
@ -293,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
@ -310,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
@ -327,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
@ -344,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
@ -361,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
@ -374,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);
@ -385,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
@ -493,6 +524,8 @@ SDL_COMPILE_TIME_ASSERT(SDL_VirtualJoystickDesc_SIZE,
* \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
@ -513,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
@ -525,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);
@ -548,6 +585,8 @@ 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
@ -574,6 +613,8 @@ 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
@ -599,6 +640,8 @@ 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
@ -624,6 +667,8 @@ 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
@ -656,6 +701,8 @@ 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
@ -684,6 +731,8 @@ 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
@ -714,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);
@ -731,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
@ -744,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
@ -759,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
@ -774,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
@ -790,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
@ -805,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
@ -819,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
@ -833,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
@ -848,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);
@ -861,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);
@ -871,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
@ -890,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
@ -903,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);
@ -914,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);
@ -929,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
@ -950,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
@ -966,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
@ -982,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
@ -1000,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
@ -1016,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
@ -1028,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);
@ -1050,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
@ -1068,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);
@ -1087,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
@ -1102,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
@ -1126,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
@ -1149,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);
@ -1176,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
@ -1198,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);
@ -1211,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);
@ -1220,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
@ -1234,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);
@ -1255,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

@ -266,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

@ -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;
/**

View file

@ -74,6 +74,13 @@ extern "C" {
*/
#define SDL_SOFTWARE_RENDERER "software"
/**
* The name of the GPU renderer.
*
* \since This macro is available since SDL 3.4.0.
*/
#define SDL_GPU_RENDERER "gpu"
/**
* Vertex structure.
*
@ -122,7 +129,7 @@ typedef enum SDL_RendererLogicalPresentation
{
SDL_LOGICAL_PRESENTATION_DISABLED, /**< There is no logical size in effect */
SDL_LOGICAL_PRESENTATION_STRETCH, /**< The rendered content is stretched to the output resolution */
SDL_LOGICAL_PRESENTATION_LETTERBOX, /**< The rendered content is fit to the largest dimension and the other dimension is letterboxed with black bars */
SDL_LOGICAL_PRESENTATION_LETTERBOX, /**< The rendered content is fit to the largest dimension and the other dimension is letterboxed with the clear color */
SDL_LOGICAL_PRESENTATION_OVERSCAN, /**< The rendered content is fit to the smallest dimension and the other dimension extends beyond the output bounds */
SDL_LOGICAL_PRESENTATION_INTEGER_SCALE /**< The rendered content is scaled up by integer multiples to fit the output resolution */
} SDL_RendererLogicalPresentation;
@ -285,6 +292,8 @@ extern SDL_DECLSPEC SDL_Renderer * SDLCALL SDL_CreateRenderer(SDL_Window *window
*
* With the SDL GPU renderer (since SDL 3.4.0):
*
* - `SDL_PROP_RENDERER_CREATE_GPU_DEVICE_POINTER`: the device to use with the
* renderer, optional.
* - `SDL_PROP_RENDERER_CREATE_GPU_SHADERS_SPIRV_BOOLEAN`: the app is able to
* provide SPIR-V shaders to SDL_GPURenderState, optional.
* - `SDL_PROP_RENDERER_CREATE_GPU_SHADERS_DXIL_BOOLEAN`: the app is able to
@ -328,6 +337,7 @@ extern SDL_DECLSPEC SDL_Renderer * SDLCALL SDL_CreateRendererWithProperties(SDL_
#define SDL_PROP_RENDERER_CREATE_SURFACE_POINTER "SDL.renderer.create.surface"
#define SDL_PROP_RENDERER_CREATE_OUTPUT_COLORSPACE_NUMBER "SDL.renderer.create.output_colorspace"
#define SDL_PROP_RENDERER_CREATE_PRESENT_VSYNC_NUMBER "SDL.renderer.create.present_vsync"
#define SDL_PROP_RENDERER_CREATE_GPU_DEVICE_POINTER "SDL.renderer.create.gpu.device"
#define SDL_PROP_RENDERER_CREATE_GPU_SHADERS_SPIRV_BOOLEAN "SDL.renderer.create.gpu.shaders_spirv"
#define SDL_PROP_RENDERER_CREATE_GPU_SHADERS_DXIL_BOOLEAN "SDL.renderer.create.gpu.shaders_dxil"
#define SDL_PROP_RENDERER_CREATE_GPU_SHADERS_MSL_BOOLEAN "SDL.renderer.create.gpu.shaders_msl"
@ -339,35 +349,51 @@ extern SDL_DECLSPEC SDL_Renderer * SDLCALL SDL_CreateRendererWithProperties(SDL_
#define SDL_PROP_RENDERER_CREATE_VULKAN_PRESENT_QUEUE_FAMILY_INDEX_NUMBER "SDL.renderer.create.vulkan.present_queue_family_index"
/**
* Create a 2D GPU rendering context for a window, with support for the
* specified shader format.
* Create a 2D GPU rendering context.
*
* This is a convenience function to create a SDL GPU backed renderer,
* intended to be used with SDL_GPURenderState. The resulting renderer will
* support shaders in one of the specified shader formats.
* The GPU device to use is passed in as a parameter. If this is NULL, then a
* device will be created normally and can be retrieved using
* SDL_GetGPURendererDevice().
*
* If no available GPU driver supports any of the specified shader formats,
* this function will fail.
* The window to use is passed in as a parameter. If this is NULL, then this
* will become an offscreen renderer. In that case, you should call
* SDL_SetRenderTarget() to setup rendering to a texture, and then call
* SDL_RenderPresent() normally to complete drawing a frame.
*
* \param window the window where rendering is displayed.
* \param format_flags a bitflag indicating which shader formats the app is
* able to provide.
* \param device a pointer filled with the associated GPU device, or NULL on
* error.
* \param device the GPU device to use with the renderer, or NULL to create a
* device.
* \param window the window where rendering is displayed, or NULL to create an
* offscreen renderer.
* \returns a valid rendering context or NULL if there was an error; call
* SDL_GetError() for more information.
*
* \threadsafety This function should only be called on the main thread.
* \threadsafety If this function is called with a valid GPU device, it should
* be called on the thread that created the device. If this
* function is called with a valid window, it should be called
* on the thread that created the window.
*
* \since This function is available since SDL 3.4.0.
*
* \sa SDL_CreateRendererWithProperties
* \sa SDL_GetGPUShaderFormats
* \sa SDL_GetGPURendererDevice
* \sa SDL_CreateGPUShader
* \sa SDL_CreateGPURenderState
* \sa SDL_SetRenderGPUState
* \sa SDL_SetGPURenderState
*/
extern SDL_DECLSPEC SDL_Renderer * SDLCALL SDL_CreateGPURenderer(SDL_Window *window, SDL_GPUShaderFormat format_flags, SDL_GPUDevice **device);
extern SDL_DECLSPEC SDL_Renderer * SDLCALL SDL_CreateGPURenderer(SDL_GPUDevice *device, SDL_Window *window);
/**
* Return the GPU device used by a renderer.
*
* \param renderer the rendering context.
* \returns the GPU device used by the renderer, or NULL if the renderer is
* not a GPU renderer; 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_GPUDevice * SDLCALL SDL_GetGPURendererDevice(SDL_Renderer *renderer);
/**
* Create a 2D software rendering context for a surface.
@ -382,7 +408,7 @@ extern SDL_DECLSPEC SDL_Renderer * SDLCALL SDL_CreateGPURenderer(SDL_Window *win
* \returns a valid rendering context or NULL if there was an error; call
* SDL_GetError() for more information.
*
* \threadsafety This function should only be called on the main thread.
* \threadsafety It is safe to call this function from any thread.
*
* \since This function is available since SDL 3.2.0.
*
@ -660,6 +686,9 @@ extern SDL_DECLSPEC SDL_Texture * SDLCALL SDL_CreateTextureFromSurface(SDL_Rende
* pixels, required
* - `SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER`: the height of the texture in
* pixels, required
* - `SDL_PROP_TEXTURE_CREATE_PALETTE_POINTER`: an SDL_Palette to use with
* palettized texture formats. This can be set later with
* SDL_SetTexturePalette()
* - `SDL_PROP_TEXTURE_CREATE_SDR_WHITE_POINT_FLOAT`: for HDR10 and floating
* point textures, this defines the value of 100% diffuse white, with higher
* values being displayed in the High Dynamic Range headroom. This defaults
@ -759,6 +788,7 @@ extern SDL_DECLSPEC SDL_Texture * SDLCALL SDL_CreateTextureWithProperties(SDL_Re
#define SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER "SDL.texture.create.access"
#define SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER "SDL.texture.create.width"
#define SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER "SDL.texture.create.height"
#define SDL_PROP_TEXTURE_CREATE_PALETTE_POINTER "SDL.texture.create.palette"
#define SDL_PROP_TEXTURE_CREATE_SDR_WHITE_POINT_FLOAT "SDL.texture.create.SDR_white_point"
#define SDL_PROP_TEXTURE_CREATE_HDR_HEADROOM_FLOAT "SDL.texture.create.HDR_headroom"
#define SDL_PROP_TEXTURE_CREATE_D3D11_TEXTURE_POINTER "SDL.texture.create.d3d11.texture"
@ -856,6 +886,17 @@ extern SDL_DECLSPEC SDL_Texture * SDLCALL SDL_CreateTextureWithProperties(SDL_Re
* - `SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_TARGET_NUMBER`: the GLenum for the
* texture target (`GL_TEXTURE_2D`, `GL_TEXTURE_EXTERNAL_OES`, etc)
*
* With the gpu renderer:
*
* - `SDL_PROP_TEXTURE_GPU_TEXTURE_POINTER`: the SDL_GPUTexture associated
* with the texture
* - `SDL_PROP_TEXTURE_GPU_TEXTURE_UV_POINTER`: the SDL_GPUTexture associated
* with the UV plane of an NV12 texture
* - `SDL_PROP_TEXTURE_GPU_TEXTURE_U_POINTER`: the SDL_GPUTexture associated
* with the U plane of a YUV texture
* - `SDL_PROP_TEXTURE_GPU_TEXTURE_V_POINTER`: the SDL_GPUTexture associated
* with the V plane of a YUV texture
*
* \param texture the texture to query.
* \returns a valid property ID on success or 0 on failure; call
* SDL_GetError() for more information.
@ -892,6 +933,10 @@ extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetTextureProperties(SDL_Textur
#define SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_V_NUMBER "SDL.texture.opengles2.texture_v"
#define SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_TARGET_NUMBER "SDL.texture.opengles2.target"
#define SDL_PROP_TEXTURE_VULKAN_TEXTURE_NUMBER "SDL.texture.vulkan.texture"
#define SDL_PROP_TEXTURE_GPU_TEXTURE_POINTER "SDL.texture.gpu.texture"
#define SDL_PROP_TEXTURE_GPU_TEXTURE_UV_POINTER "SDL.texture.gpu.texture_uv"
#define SDL_PROP_TEXTURE_GPU_TEXTURE_U_POINTER "SDL.texture.gpu.texture_u"
#define SDL_PROP_TEXTURE_GPU_TEXTURE_V_POINTER "SDL.texture.gpu.texture_v"
/**
* Get the renderer that created an SDL_Texture.
@ -923,6 +968,43 @@ extern SDL_DECLSPEC SDL_Renderer * SDLCALL SDL_GetRendererFromTexture(SDL_Textur
*/
extern SDL_DECLSPEC bool SDLCALL SDL_GetTextureSize(SDL_Texture *texture, float *w, float *h);
/**
* Set the palette used by a texture.
*
* Setting the palette keeps an internal reference to the palette, which can
* be safely destroyed afterwards.
*
* A single palette can be shared with many textures.
*
* \param texture the texture to update.
* \param palette the SDL_Palette structure to use.
* \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.
*
* \sa SDL_CreatePalette
* \sa SDL_GetTexturePalette
*/
extern SDL_DECLSPEC bool SDLCALL SDL_SetTexturePalette(SDL_Texture *texture, SDL_Palette *palette);
/**
* Get the palette used by a texture.
*
* \param texture the texture to query.
* \returns a pointer to the palette used by the texture, or NULL if there is
* no palette used.
*
* \threadsafety This function should only be called on the main thread.
*
* \since This function is available since SDL 3.4.0.
*
* \sa SDL_SetTexturePalette
*/
extern SDL_DECLSPEC SDL_Palette * SDLCALL SDL_GetTexturePalette(SDL_Texture *texture);
/**
* Set an additional color value multiplied into render copy operations.
*
@ -1152,6 +1234,8 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetTextureBlendMode(SDL_Texture *texture, S
* The default texture scale mode is SDL_SCALEMODE_LINEAR.
*
* If the scale mode is not supported, the closest supported mode is chosen.
* Palettized textures will use SDL_SCALEMODE_PIXELART instead of
* SDL_SCALEMODE_LINEAR.
*
* \param texture the texture to update.
* \param scaleMode the SDL_ScaleMode to use for texture scaling.
@ -1445,14 +1529,6 @@ extern SDL_DECLSPEC SDL_Texture * SDLCALL SDL_GetRenderTarget(SDL_Renderer *rend
* specific dimensions but to make fonts look sharp, the app turns off logical
* presentation while drawing text, for example.
*
* For the renderer's window, letterboxing is drawn into the framebuffer if
* logical presentation is enabled during SDL_RenderPresent; be sure to
* reenable it before presenting if you were toggling it, otherwise the
* letterbox areas might have artifacts from previous frames (or artifacts
* from external overlays, etc). Letterboxing is never drawn into texture
* render targets; be sure to call SDL_RenderClear() before drawing into the
* texture so the letterboxing areas are cleared, if appropriate.
*
* You can convert coordinates in an event into rendering coordinates using
* SDL_ConvertEventToRenderCoordinates().
*
@ -1477,15 +1553,16 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetRenderLogicalPresentation(SDL_Renderer *
* Get device independent resolution and presentation mode for rendering.
*
* This function gets the width and height of the logical rendering output, or
* the output size in pixels if a logical resolution is not enabled.
* 0 if a logical resolution is not enabled.
*
* Each render target has its own logical presentation state. This function
* gets the state for the current render target.
*
* \param renderer the rendering context.
* \param w an int to be filled with the width.
* \param h an int to be filled with the height.
* \param mode the presentation mode used.
* \param w an int filled with the logical presentation width.
* \param h an int filled with the logical presentation height.
* \param mode a variable filled with the logical presentation mode being
* used.
* \returns true on success or false on failure; call SDL_GetError() for more
* information.
*
@ -2720,8 +2797,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_GetRenderVSync(SDL_Renderer *renderer, int
* break. If the text goes out of the window, it's gone.
*
* For serious text rendering, there are several good options, such as
* [SDL_ttf](https://wiki.libsdl.org/SDL3_ttf/FrontPage)
* , stb_truetype, or other external libraries.
* SDL_ttf, stb_truetype, or other external libraries.
*
* On first use, this will create an internal texture for rendering glyphs.
* This texture will live until the renderer is destroyed.
@ -2838,7 +2914,7 @@ typedef struct SDL_GPURenderStateCreateInfo
*
* \sa SDL_CreateGPURenderState
* \sa SDL_SetGPURenderStateFragmentUniforms
* \sa SDL_SetRenderGPUState
* \sa SDL_SetGPURenderState
* \sa SDL_DestroyGPURenderState
*/
typedef struct SDL_GPURenderState SDL_GPURenderState;
@ -2857,7 +2933,7 @@ typedef struct SDL_GPURenderState SDL_GPURenderState;
* \since This function is available since SDL 3.4.0.
*
* \sa SDL_SetGPURenderStateFragmentUniforms
* \sa SDL_SetRenderGPUState
* \sa SDL_SetGPURenderState
* \sa SDL_DestroyGPURenderState
*/
extern SDL_DECLSPEC SDL_GPURenderState * SDLCALL SDL_CreateGPURenderState(SDL_Renderer *renderer, SDL_GPURenderStateCreateInfo *createinfo);
@ -2898,7 +2974,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetGPURenderStateFragmentUniforms(SDL_GPURe
*
* \since This function is available since SDL 3.4.0.
*/
extern SDL_DECLSPEC bool SDLCALL SDL_SetRenderGPUState(SDL_Renderer *renderer, SDL_GPURenderState *state);
extern SDL_DECLSPEC bool SDLCALL SDL_SetGPURenderState(SDL_Renderer *renderer, SDL_GPURenderState *state);
/**
* Destroy custom GPU render state.

View file

@ -49,10 +49,30 @@
#include <SDL3/SDL_platform_defines.h>
#include <stdarg.h>
#include <stdint.h>
#include <string.h>
#include <wchar.h>
/* Most everything except Visual Studio 2008 and earlier has stdint.h now */
#if defined(_MSC_VER) && (_MSC_VER < 1600)
typedef signed __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef signed __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef signed __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
#ifndef _UINTPTR_T_DEFINED
#ifdef _WIN64
typedef unsigned __int64 uintptr_t;
#else
typedef unsigned int uintptr_t;
#endif
#endif
#else
#include <stdint.h>
#endif
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
defined(SDL_INCLUDE_INTTYPES_H)
#include <inttypes.h>

View file

@ -86,7 +86,7 @@ typedef enum SDL_ScaleMode
SDL_SCALEMODE_INVALID = -1,
SDL_SCALEMODE_NEAREST, /**< nearest pixel sampling */
SDL_SCALEMODE_LINEAR, /**< linear filtering */
SDL_SCALEMODE_PIXELART /**< nearest pixel sampling with improved scaling for pixel art */
SDL_SCALEMODE_PIXELART /**< nearest pixel sampling with improved scaling for pixel art, available since SDL 3.4.0 */
} SDL_ScaleMode;
/**
@ -327,6 +327,9 @@ extern SDL_DECLSPEC SDL_Palette * SDLCALL SDL_CreateSurfacePalette(SDL_Surface *
/**
* Set the palette used by a surface.
*
* Setting the palette keeps an internal reference to the palette, which can
* be safely destroyed afterwards.
*
* A single palette can be shared with many surfaces.
*
* \param surface the SDL_Surface structure to update.

View file

@ -34,7 +34,7 @@
* This category covers measuring time elapsed (SDL_GetTicks(),
* SDL_GetPerformanceCounter()), putting a thread to sleep for a certain
* amount of time (SDL_Delay(), SDL_DelayNS(), SDL_DelayPrecise()), and firing
* a callback function after a certain amount of time has elasped
* a callback function after a certain amount of time has elapsed
* (SDL_AddTimer(), etc).
*
* There are also useful macros to convert between time units, like

View file

@ -226,6 +226,8 @@ typedef Uint64 SDL_WindowFlags;
* SDL_WINDOWPOS_UNDEFINED or SDL_WINDOWPOS_UNDEFINED_DISPLAY.
*
* \since This macro is available since SDL 3.2.0.
*
* \sa SDL_SetWindowPosition
*/
#define SDL_WINDOWPOS_UNDEFINED_MASK 0x1FFF0000u
@ -238,6 +240,8 @@ typedef Uint64 SDL_WindowFlags;
* \param X the SDL_DisplayID of the display to use.
*
* \since This macro is available since SDL 3.2.0.
*
* \sa SDL_SetWindowPosition
*/
#define SDL_WINDOWPOS_UNDEFINED_DISPLAY(X) (SDL_WINDOWPOS_UNDEFINED_MASK|(X))
@ -247,6 +251,8 @@ typedef Uint64 SDL_WindowFlags;
* This always uses the primary display.
*
* \since This macro is available since SDL 3.2.0.
*
* \sa SDL_SetWindowPosition
*/
#define SDL_WINDOWPOS_UNDEFINED SDL_WINDOWPOS_UNDEFINED_DISPLAY(0)
@ -256,6 +262,8 @@ typedef Uint64 SDL_WindowFlags;
* \param X the window position value.
*
* \since This macro is available since SDL 3.2.0.
*
* \sa SDL_SetWindowPosition
*/
#define SDL_WINDOWPOS_ISUNDEFINED(X) (((X)&0xFFFF0000) == SDL_WINDOWPOS_UNDEFINED_MASK)
@ -266,6 +274,8 @@ typedef Uint64 SDL_WindowFlags;
* SDL_WINDOWPOS_CENTERED or SDL_WINDOWPOS_CENTERED_DISPLAY.
*
* \since This macro is available since SDL 3.2.0.
*
* \sa SDL_SetWindowPosition
*/
#define SDL_WINDOWPOS_CENTERED_MASK 0x2FFF0000u
@ -278,6 +288,8 @@ typedef Uint64 SDL_WindowFlags;
* \param X the SDL_DisplayID of the display to use.
*
* \since This macro is available since SDL 3.2.0.
*
* \sa SDL_SetWindowPosition
*/
#define SDL_WINDOWPOS_CENTERED_DISPLAY(X) (SDL_WINDOWPOS_CENTERED_MASK|(X))
@ -287,6 +299,8 @@ typedef Uint64 SDL_WindowFlags;
* This always uses the primary display.
*
* \since This macro is available since SDL 3.2.0.
*
* \sa SDL_SetWindowPosition
*/
#define SDL_WINDOWPOS_CENTERED SDL_WINDOWPOS_CENTERED_DISPLAY(0)
@ -296,6 +310,8 @@ typedef Uint64 SDL_WindowFlags;
* \param X the window position value.
*
* \since This macro is available since SDL 3.2.0.
*
* \sa SDL_GetWindowPosition
*/
#define SDL_WINDOWPOS_ISCENTERED(X) \
(((X)&0xFFFF0000) == SDL_WINDOWPOS_CENTERED_MASK)
@ -1337,6 +1353,15 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreatePopupWindow(SDL_Window *paren
*
* - `SDL_PROP_WINDOW_CREATE_EMSCRIPTEN_CANVAS_ID_STRING`: the id given to the
* canvas element. This should start with a '#' sign
* - `SDL_PROP_WINDOW_CREATE_EMSCRIPTEN_FILL_DOCUMENT_BOOLEAN`: true to make
* the canvas element fill 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.
* 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.
* Default false.
* - `SDL_PROP_WINDOW_CREATE_EMSCRIPTEN_KEYBOARD_ELEMENT_STRING`: override the
* binding element for keyboard inputs for this canvas. The variable can be
* one of:
@ -1410,6 +1435,7 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreateWindowWithProperties(SDL_Prop
#define SDL_PROP_WINDOW_CREATE_WIN32_PIXEL_FORMAT_HWND_POINTER "SDL.window.create.win32.pixel_format_hwnd"
#define SDL_PROP_WINDOW_CREATE_X11_WINDOW_NUMBER "SDL.window.create.x11.window"
#define SDL_PROP_WINDOW_CREATE_EMSCRIPTEN_CANVAS_ID_STRING "SDL.window.create.emscripten.canvas_id"
#define SDL_PROP_WINDOW_CREATE_EMSCRIPTEN_FILL_DOCUMENT_BOOLEAN "SDL.window.create.emscripten.fill_document"
#define SDL_PROP_WINDOW_CREATE_EMSCRIPTEN_KEYBOARD_ELEMENT_STRING "SDL.window.create.emscripten.keyboard_element"
/**
@ -1579,6 +1605,9 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_GetWindowParent(SDL_Window *window)
*
* - `SDL_PROP_WINDOW_EMSCRIPTEN_CANVAS_ID_STRING`: the id the canvas element
* will have
* - `SDL_PROP_WINDOW_EMSCRIPTEN_FILL_DOCUMENT_BOOLEAN`: true if the canvas is
* set to consume the entire browser window, bypassing some SDL window
* functionality.
* - `SDL_PROP_WINDOW_EMSCRIPTEN_KEYBOARD_ELEMENT_STRING`: the keyboard
* element that associates keyboard events to this window
*
@ -1628,6 +1657,7 @@ extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetWindowProperties(SDL_Window
#define SDL_PROP_WINDOW_X11_SCREEN_NUMBER "SDL.window.x11.screen"
#define SDL_PROP_WINDOW_X11_WINDOW_NUMBER "SDL.window.x11.window"
#define SDL_PROP_WINDOW_EMSCRIPTEN_CANVAS_ID_STRING "SDL.window.emscripten.canvas_id"
#define SDL_PROP_WINDOW_EMSCRIPTEN_FILL_DOCUMENT_BOOLEAN "SDL.window.emscripten.fill_document"
#define SDL_PROP_WINDOW_EMSCRIPTEN_KEYBOARD_ELEMENT_STRING "SDL.window.emscripten.keyboard_element"
/**

View file

@ -214,7 +214,7 @@
#define SDL_FSOPS_POSIX 1
/* enable camera support */
#ifndef SDL_PLATFORM_TVOS
#if !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS)
#define SDL_CAMERA_DRIVER_COREMEDIA 1
#endif

View file

@ -148,7 +148,7 @@ static bool SDL_ValidMetadataProperty(const char *name)
bool SDL_SetAppMetadataProperty(const char *name, const char *value)
{
if (!SDL_ValidMetadataProperty(name)) {
CHECK_PARAM(!SDL_ValidMetadataProperty(name)) {
return SDL_InvalidParamError("name");
}
@ -157,7 +157,7 @@ bool SDL_SetAppMetadataProperty(const char *name, const char *value)
const char *SDL_GetAppMetadataProperty(const char *name)
{
if (!SDL_ValidMetadataProperty(name)) {
CHECK_PARAM(!SDL_ValidMetadataProperty(name)) {
SDL_InvalidParamError("name");
return NULL;
}
@ -845,9 +845,7 @@ SDL_Sandbox SDL_GetSandbox(void)
#ifdef SDL_PLATFORM_WIN32
#if (!defined(HAVE_LIBC) || defined(__WATCOMC__)) && !defined(SDL_STATIC_LIB)
// FIXME: Still need to include DllMain() on Watcom C ?
#if !defined(HAVE_LIBC) && !defined(SDL_STATIC_LIB)
BOOL APIENTRY MINGW32_FORCEALIGN _DllMainCRTStartup(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call) {

View file

@ -120,23 +120,10 @@ static void SDL_GenerateAssertionReport(void)
}
}
/* This is not declared in any header, although it is shared between some
parts of SDL, because we don't want anything calling it without an
extremely good reason. */
#ifdef __WATCOMC__
extern void SDL_ExitProcess(int exitcode);
#pragma aux SDL_ExitProcess aborts;
#endif
extern SDL_NORETURN void SDL_ExitProcess(int exitcode);
#ifdef __WATCOMC__
static void SDL_AbortAssertion(void);
#pragma aux SDL_AbortAssertion aborts;
#endif
static SDL_NORETURN void SDL_AbortAssertion(void)
{
SDL_Quit();
SDL_ExitProcess(42);
SDL_abort();
}
static SDL_AssertState SDLCALL SDL_PromptAssertion(const SDL_AssertData *data, void *userdata)
@ -361,7 +348,7 @@ SDL_AssertState SDL_ReportAssertion(SDL_AssertData *data, const char *func, cons
if (assertion_running == 2) {
SDL_AbortAssertion();
} else if (assertion_running == 3) { // Abort asserted!
SDL_ExitProcess(42);
SDL_abort();
} else {
while (1) { // do nothing but spin; what else can you do?!
}

View file

@ -292,7 +292,7 @@ static bool maybe_resize(SDL_HashTable *ht)
bool SDL_InsertIntoHashTable(SDL_HashTable *table, const void *key, const void *value, bool replace)
{
if (!table) {
CHECK_PARAM(!table) {
return SDL_InvalidParamError("table");
}
@ -338,7 +338,7 @@ bool SDL_InsertIntoHashTable(SDL_HashTable *table, const void *key, const void *
bool SDL_FindInHashTable(const SDL_HashTable *table, const void *key, const void **value)
{
if (!table) {
CHECK_PARAM(!table) {
if (value) {
*value = NULL;
}
@ -364,7 +364,7 @@ bool SDL_FindInHashTable(const SDL_HashTable *table, const void *key, const void
bool SDL_RemoveFromHashTable(SDL_HashTable *table, const void *key)
{
if (!table) {
CHECK_PARAM(!table) {
return SDL_InvalidParamError("table");
}
@ -384,9 +384,10 @@ bool SDL_RemoveFromHashTable(SDL_HashTable *table, const void *key)
bool SDL_IterateHashTable(const SDL_HashTable *table, SDL_HashTableIterateCallback callback, void *userdata)
{
if (!table) {
CHECK_PARAM(!table) {
return SDL_InvalidParamError("table");
} else if (!callback) {
}
CHECK_PARAM(!callback) {
return SDL_InvalidParamError("callback");
}
@ -410,7 +411,7 @@ bool SDL_IterateHashTable(const SDL_HashTable *table, SDL_HashTableIterateCallba
bool SDL_HashTableEmpty(SDL_HashTable *table)
{
if (!table) {
CHECK_PARAM(!table) {
return SDL_InvalidParamError("table");
}

View file

@ -104,7 +104,7 @@ static const char *GetHintEnvironmentVariable(const char *name)
bool SDL_SetHintWithPriority(const char *name, const char *value, SDL_HintPriority priority)
{
if (!name || !*name) {
CHECK_PARAM(!name || !*name) {
return SDL_InvalidParamError("name");
}
@ -165,7 +165,7 @@ bool SDL_SetHintWithPriority(const char *name, const char *value, SDL_HintPriori
bool SDL_ResetHint(const char *name)
{
if (!name || !*name) {
CHECK_PARAM(!name || !*name) {
return SDL_InvalidParamError("name");
}
@ -316,9 +316,10 @@ bool SDL_GetHintBoolean(const char *name, bool default_value)
bool SDL_AddHintCallback(const char *name, SDL_HintCallback callback, void *userdata)
{
if (!name || !*name) {
CHECK_PARAM(!name || !*name) {
return SDL_InvalidParamError("name");
} else if (!callback) {
}
CHECK_PARAM(!callback) {
return SDL_InvalidParamError("callback");
}

View file

@ -266,12 +266,43 @@ extern "C" {
#include "SDL_utils_c.h"
#include "SDL_hashtable.h"
/* SDL_ExitProcess is not declared in any public header, although
it is shared between some parts of SDL, because we don't want
anything calling it without an extremely good reason. */
extern SDL_NORETURN void SDL_ExitProcess(int exitcode);
#ifdef HAVE_LIBC
#define SDL_abort() abort()
#else
#define SDL_abort() do { \
SDL_TriggerBreakpoint(); \
SDL_ExitProcess(42); \
} while (0)
#endif
#define PUSH_SDL_ERROR() \
{ char *_error = SDL_strdup(SDL_GetError());
#define POP_SDL_ERROR() \
SDL_SetError("%s", _error); SDL_free(_error); }
#if defined(SDL_DISABLE_INVALID_PARAMS)
#ifdef DEBUG
// If you define SDL_DISABLE_INVALID_PARAMS, you're promising that you'll
// never pass an invalid parameter to SDL, since it may crash or lead to
// hard to diagnose bugs. Let's assert that this is true in debug builds.
#define OBJECT_VALIDATION_REQUIRED
#define CHECK_PARAM(invalid) SDL_assert_always(!(invalid)); if (false)
#else
#define CHECK_PARAM(invalid) if (false)
#endif
#elif defined(SDL_ASSERT_INVALID_PARAMS)
#define OBJECT_VALIDATION_REQUIRED
#define CHECK_PARAM(invalid) SDL_assert_always(!(invalid)); if (invalid)
#else
#define CHECK_PARAM(invalid) if (invalid)
#endif
// Do any initialization that needs to happen before threads are started
extern void SDL_InitMainThread(void);

View file

@ -392,6 +392,9 @@ void SDL_ResetLogPriorities(void)
SDL_LockMutex(SDL_log_lock);
{
const char *env = SDL_getenv("DEBUG_INVOCATION");
bool debug = (env && *env && *env != '0');
CleanupLogPriorities();
SDL_log_default_priority = SDL_LOG_PRIORITY_INVALID;
@ -414,7 +417,11 @@ void SDL_ResetLogPriorities(void)
switch (i) {
case SDL_LOG_CATEGORY_APPLICATION:
SDL_log_priorities[i] = SDL_LOG_PRIORITY_INFO;
if (debug) {
SDL_log_priorities[i] = SDL_LOG_PRIORITY_DEBUG;
} else {
SDL_log_priorities[i] = SDL_LOG_PRIORITY_INFO;
}
break;
case SDL_LOG_CATEGORY_ASSERT:
SDL_log_priorities[i] = SDL_LOG_PRIORITY_WARN;
@ -423,7 +430,11 @@ void SDL_ResetLogPriorities(void)
SDL_log_priorities[i] = SDL_LOG_PRIORITY_VERBOSE;
break;
default:
SDL_log_priorities[i] = SDL_LOG_PRIORITY_ERROR;
if (debug) {
SDL_log_priorities[i] = SDL_LOG_PRIORITY_DEBUG;
} else {
SDL_log_priorities[i] = SDL_LOG_PRIORITY_ERROR;
}
break;
}
}
@ -467,7 +478,7 @@ bool SDL_SetLogPriorityPrefix(SDL_LogPriority priority, const char *prefix)
{
char *prefix_copy;
if (priority <= SDL_LOG_PRIORITY_INVALID || priority >= SDL_LOG_PRIORITY_COUNT) {
CHECK_PARAM(priority <= SDL_LOG_PRIORITY_INVALID || priority >= SDL_LOG_PRIORITY_COUNT) {
return SDL_InvalidParamError("priority");
}

View file

@ -250,10 +250,10 @@ static bool SDLCALL CopyOneProperty(void *userdata, const SDL_HashTable *table,
bool SDL_CopyProperties(SDL_PropertiesID src, SDL_PropertiesID dst)
{
if (!src) {
CHECK_PARAM(!src) {
return SDL_InvalidParamError("src");
}
if (!dst) {
CHECK_PARAM(!dst) {
return SDL_InvalidParamError("dst");
}
@ -261,11 +261,11 @@ bool SDL_CopyProperties(SDL_PropertiesID src, SDL_PropertiesID dst)
SDL_Properties *dst_properties = NULL;
SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)src, (const void **)&src_properties);
if (!src_properties) {
CHECK_PARAM(!src_properties) {
return SDL_InvalidParamError("src");
}
SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)dst, (const void **)&dst_properties);
if (!dst_properties) {
CHECK_PARAM(!dst_properties) {
return SDL_InvalidParamError("dst");
}
@ -287,12 +287,12 @@ bool SDL_LockProperties(SDL_PropertiesID props)
{
SDL_Properties *properties = NULL;
if (!props) {
CHECK_PARAM(!props) {
return SDL_InvalidParamError("props");
}
SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties);
if (!properties) {
CHECK_PARAM(!properties) {
return SDL_InvalidParamError("props");
}
@ -321,17 +321,17 @@ static bool SDL_PrivateSetProperty(SDL_PropertiesID props, const char *name, SDL
SDL_Properties *properties = NULL;
bool result = true;
if (!props) {
CHECK_PARAM(!props) {
SDL_FreePropertyWithCleanup(NULL, property, NULL, true);
return SDL_InvalidParamError("props");
}
if (!name || !*name) {
CHECK_PARAM(!name || !*name) {
SDL_FreePropertyWithCleanup(NULL, property, NULL, true);
return SDL_InvalidParamError("name");
}
SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties);
if (!properties) {
CHECK_PARAM(!properties) {
SDL_FreePropertyWithCleanup(NULL, property, NULL, true);
return SDL_InvalidParamError("props");
}
@ -755,15 +755,15 @@ bool SDL_EnumerateProperties(SDL_PropertiesID props, SDL_EnumeratePropertiesCall
{
SDL_Properties *properties = NULL;
if (!props) {
CHECK_PARAM(!props) {
return SDL_InvalidParamError("props");
}
if (!callback) {
CHECK_PARAM(!callback) {
return SDL_InvalidParamError("callback");
}
SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties);
if (!properties) {
CHECK_PARAM(!properties) {
return SDL_InvalidParamError("props");
}

View file

@ -137,6 +137,30 @@ Uint32 SDL_GetNextObjectID(void)
static SDL_InitState SDL_objects_init;
static SDL_HashTable *SDL_objects;
bool SDL_object_validation = true;
static void SDLCALL SDL_InvalidParamChecksChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
bool validation_enabled = true;
#ifndef OBJECT_VALIDATION_REQUIRED
if (hint) {
switch (*hint) {
case '0':
case '1':
validation_enabled = false;
break;
case '2':
validation_enabled = true;
break;
default:
break;
}
}
#endif // !OBJECT_VALIDATION_REQUIRED
SDL_object_validation = validation_enabled;
}
static Uint32 SDLCALL SDL_HashObject(void *unused, const void *key)
{
@ -159,6 +183,7 @@ void SDL_SetObjectValid(void *object, SDL_ObjectType type, bool valid)
if (!initialized) {
return;
}
SDL_AddHintCallback(SDL_HINT_INVALID_PARAM_CHECKS, SDL_InvalidParamChecksChanged, NULL);
}
if (valid) {
@ -168,12 +193,8 @@ void SDL_SetObjectValid(void *object, SDL_ObjectType type, bool valid)
}
}
bool SDL_ObjectValid(void *object, SDL_ObjectType type)
bool SDL_FindObject(void *object, SDL_ObjectType type)
{
if (!object) {
return false;
}
const void *object_type;
if (!SDL_FindInHashTable(SDL_objects, object, &object_type)) {
return false;
@ -242,6 +263,7 @@ void SDL_SetObjectsInvalid(void)
SDL_DestroyHashTable(SDL_objects);
SDL_objects = NULL;
SDL_SetInitialized(&SDL_objects_init, false);
SDL_RemoveHintCallback(SDL_HINT_INVALID_PARAM_CHECKS, SDL_InvalidParamChecksChanged, NULL);
}
}

View file

@ -67,10 +67,25 @@ typedef enum
extern Uint32 SDL_GetNextObjectID(void);
extern void SDL_SetObjectValid(void *object, SDL_ObjectType type, bool valid);
extern bool SDL_ObjectValid(void *object, SDL_ObjectType type);
extern bool SDL_FindObject(void *object, SDL_ObjectType type);
extern int SDL_GetObjects(SDL_ObjectType type, void **objects, int count);
extern void SDL_SetObjectsInvalid(void);
extern bool SDL_object_validation;
SDL_FORCE_INLINE bool SDL_ObjectValid(void *object, SDL_ObjectType type)
{
if (!object) {
return false;
}
if (!SDL_object_validation) {
return true;
}
return SDL_FindObject(object, type);
}
extern const char *SDL_GetPersistentString(const char *string);
extern char *SDL_CreateDeviceName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name, const char *default_name);

View file

@ -48,35 +48,6 @@
#endif
#endif
/* *INDENT-OFF* */ // clang-format off
#if defined(__WATCOMC__) && defined(__386__)
SDL_COMPILE_TIME_ASSERT(intsize, 4==sizeof(int));
#define HAVE_WATCOM_ATOMICS
extern __inline int _SDL_xchg_watcom(volatile int *a, int v);
#pragma aux _SDL_xchg_watcom = \
"lock xchg [ecx], eax" \
parm [ecx] [eax] \
value [eax] \
modify exact [eax];
extern __inline unsigned char _SDL_cmpxchg_watcom(volatile int *a, int newval, int oldval);
#pragma aux _SDL_cmpxchg_watcom = \
"lock cmpxchg [edx], ecx" \
"setz al" \
parm [edx] [ecx] [eax] \
value [al] \
modify exact [eax];
extern __inline int _SDL_xadd_watcom(volatile int *a, int v);
#pragma aux _SDL_xadd_watcom = \
"lock xadd [ecx], eax" \
parm [ecx] [eax] \
value [eax] \
modify exact [eax];
#endif // __WATCOMC__ && __386__
/* *INDENT-ON* */ // clang-format on
/*
If any of the operations are not provided then we must emulate some
of them. That means we need a nice implementation of spin locks
@ -100,7 +71,7 @@ extern __inline int _SDL_xadd_watcom(volatile int *a, int v);
Contributed by Bob Pendleton, bob@pendleton.com
*/
#if !defined(HAVE_MSC_ATOMICS) && !defined(HAVE_GCC_ATOMICS) && !defined(SDL_PLATFORM_MACOS) && !defined(SDL_PLATFORM_SOLARIS) && !defined(HAVE_WATCOM_ATOMICS)
#if !defined(HAVE_MSC_ATOMICS) && !defined(HAVE_GCC_ATOMICS) && !defined(SDL_PLATFORM_MACOS) && !defined(SDL_PLATFORM_SOLARIS)
#define EMULATE_CAS 1
#endif
@ -127,8 +98,6 @@ bool SDL_CompareAndSwapAtomicInt(SDL_AtomicInt *a, int oldval, int newval)
#ifdef HAVE_MSC_ATOMICS
SDL_COMPILE_TIME_ASSERT(atomic_cas, sizeof(long) == sizeof(a->value));
return _InterlockedCompareExchange((long *)&a->value, (long)newval, (long)oldval) == (long)oldval;
#elif defined(HAVE_WATCOM_ATOMICS)
return _SDL_cmpxchg_watcom((volatile int *)&a->value, newval, oldval);
#elif defined(HAVE_GCC_ATOMICS)
return __sync_bool_compare_and_swap(&a->value, oldval, newval);
#elif defined(SDL_PLATFORM_MACOS) // this is deprecated in 10.12 sdk; favor gcc atomics.
@ -157,9 +126,6 @@ bool SDL_CompareAndSwapAtomicU32(SDL_AtomicU32 *a, Uint32 oldval, Uint32 newval)
#ifdef HAVE_MSC_ATOMICS
SDL_COMPILE_TIME_ASSERT(atomic_cas, sizeof(long) == sizeof(a->value));
return _InterlockedCompareExchange((long *)&a->value, (long)newval, (long)oldval) == (long)oldval;
#elif defined(HAVE_WATCOM_ATOMICS)
SDL_COMPILE_TIME_ASSERT(atomic_cas, sizeof(int) == sizeof(a->value));
return _SDL_cmpxchg_watcom((volatile int *)&a->value, (int)newval, (int)oldval);
#elif defined(HAVE_GCC_ATOMICS)
return __sync_bool_compare_and_swap(&a->value, oldval, newval);
#elif defined(SDL_PLATFORM_MACOS) // this is deprecated in 10.12 sdk; favor gcc atomics.
@ -187,8 +153,6 @@ bool SDL_CompareAndSwapAtomicPointer(void **a, void *oldval, void *newval)
{
#ifdef HAVE_MSC_ATOMICS
return _InterlockedCompareExchangePointer(a, newval, oldval) == oldval;
#elif defined(HAVE_WATCOM_ATOMICS)
return _SDL_cmpxchg_watcom((int *)a, (long)newval, (long)oldval);
#elif defined(HAVE_GCC_ATOMICS)
return __sync_bool_compare_and_swap(a, oldval, newval);
#elif defined(SDL_PLATFORM_MACOS) && defined(__LP64__) // this is deprecated in 10.12 sdk; favor gcc atomics.
@ -218,8 +182,6 @@ int SDL_SetAtomicInt(SDL_AtomicInt *a, int v)
#ifdef HAVE_MSC_ATOMICS
SDL_COMPILE_TIME_ASSERT(atomic_set, sizeof(long) == sizeof(a->value));
return _InterlockedExchange((long *)&a->value, v);
#elif defined(HAVE_WATCOM_ATOMICS)
return _SDL_xchg_watcom(&a->value, v);
#elif defined(HAVE_GCC_ATOMICS)
return __sync_lock_test_and_set(&a->value, v);
#elif defined(SDL_PLATFORM_SOLARIS)
@ -239,8 +201,6 @@ Uint32 SDL_SetAtomicU32(SDL_AtomicU32 *a, Uint32 v)
#ifdef HAVE_MSC_ATOMICS
SDL_COMPILE_TIME_ASSERT(atomic_set, sizeof(long) == sizeof(a->value));
return _InterlockedExchange((long *)&a->value, v);
#elif defined(HAVE_WATCOM_ATOMICS)
return _SDL_xchg_watcom(&a->value, v);
#elif defined(HAVE_GCC_ATOMICS)
return __sync_lock_test_and_set(&a->value, v);
#elif defined(SDL_PLATFORM_SOLARIS)
@ -259,8 +219,6 @@ void *SDL_SetAtomicPointer(void **a, void *v)
{
#ifdef HAVE_MSC_ATOMICS
return _InterlockedExchangePointer(a, v);
#elif defined(HAVE_WATCOM_ATOMICS)
return (void *)_SDL_xchg_watcom((int *)a, (long)v);
#elif defined(HAVE_GCC_ATOMICS)
return __sync_lock_test_and_set(a, v);
#elif defined(SDL_PLATFORM_SOLARIS)
@ -279,9 +237,6 @@ int SDL_AddAtomicInt(SDL_AtomicInt *a, int v)
#ifdef HAVE_MSC_ATOMICS
SDL_COMPILE_TIME_ASSERT(atomic_add, sizeof(long) == sizeof(a->value));
return _InterlockedExchangeAdd((long *)&a->value, v);
#elif defined(HAVE_WATCOM_ATOMICS)
SDL_COMPILE_TIME_ASSERT(atomic_add, sizeof(int) == sizeof(a->value));
return _SDL_xadd_watcom((volatile int *)&a->value, v);
#elif defined(HAVE_GCC_ATOMICS)
return __sync_fetch_and_add(&a->value, v);
#elif defined(SDL_PLATFORM_SOLARIS)
@ -303,9 +258,6 @@ Uint32 SDL_AddAtomicU32(SDL_AtomicU32 *a, int v)
#ifdef HAVE_MSC_ATOMICS
SDL_COMPILE_TIME_ASSERT(atomic_add, sizeof(long) == sizeof(a->value));
return (Uint32)_InterlockedExchangeAdd((long *)&a->value, v);
#elif defined(HAVE_WATCOM_ATOMICS)
SDL_COMPILE_TIME_ASSERT(atomic_add, sizeof(int) == sizeof(a->value));
return (Uint32)_SDL_xadd_watcom((volatile int *)&a->value, v);
#elif defined(HAVE_GCC_ATOMICS)
return __sync_fetch_and_add(&a->value, v);
#elif defined(SDL_PLATFORM_SOLARIS)
@ -329,8 +281,6 @@ int SDL_GetAtomicInt(SDL_AtomicInt *a)
#elif defined(HAVE_MSC_ATOMICS)
SDL_COMPILE_TIME_ASSERT(atomic_get, sizeof(long) == sizeof(a->value));
return _InterlockedOr((long *)&a->value, 0);
#elif defined(HAVE_WATCOM_ATOMICS)
return _SDL_xadd_watcom(&a->value, 0);
#elif defined(HAVE_GCC_ATOMICS)
return __sync_or_and_fetch(&a->value, 0);
#elif defined(SDL_PLATFORM_MACOS) // this is deprecated in 10.12 sdk; favor gcc atomics.
@ -353,9 +303,6 @@ Uint32 SDL_GetAtomicU32(SDL_AtomicU32 *a)
#elif defined(HAVE_MSC_ATOMICS)
SDL_COMPILE_TIME_ASSERT(atomic_get, sizeof(long) == sizeof(a->value));
return (Uint32)_InterlockedOr((long *)&a->value, 0);
#elif defined(HAVE_WATCOM_ATOMICS)
SDL_COMPILE_TIME_ASSERT(atomic_get, sizeof(int) == sizeof(a->value));
return (Uint32)_SDL_xadd_watcom((volatile int *)&a->value, 0);
#elif defined(HAVE_GCC_ATOMICS)
return __sync_or_and_fetch(&a->value, 0);
#elif defined(SDL_PLATFORM_MACOS) // this is deprecated in 10.12 sdk; favor gcc atomics.

View file

@ -44,18 +44,6 @@
#include <libkern/OSAtomic.h>
#endif
/* *INDENT-OFF* */ // clang-format off
#if defined(__WATCOMC__) && defined(__386__)
SDL_COMPILE_TIME_ASSERT(locksize, 4==sizeof(SDL_SpinLock));
extern __inline int _SDL_xchg_watcom(volatile int *a, int v);
#pragma aux _SDL_xchg_watcom = \
"lock xchg [ecx], eax" \
parm [ecx] [eax] \
value [eax] \
modify exact [eax];
#endif // __WATCOMC__ && __386__
/* *INDENT-ON* */ // clang-format on
// This function is where all the magic happens...
bool SDL_TryLockSpinlock(SDL_SpinLock *lock)
{
@ -69,9 +57,6 @@ bool SDL_TryLockSpinlock(SDL_SpinLock *lock)
SDL_COMPILE_TIME_ASSERT(locksize, sizeof(*lock) == sizeof(long));
return InterlockedExchange((long *)lock, 1) == 0;
#elif defined(__WATCOMC__) && defined(__386__)
return _SDL_xchg_watcom(lock, 1) == 0;
#elif defined(__GNUC__) && defined(__arm__) && \
(defined(__ARM_ARCH_3__) || defined(__ARM_ARCH_3M__) || \
defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) || \
@ -188,10 +173,6 @@ void SDL_UnlockSpinlock(SDL_SpinLock *lock)
_ReadWriteBarrier();
*lock = 0;
#elif defined(__WATCOMC__) && defined(__386__)
SDL_CompilerBarrier();
*lock = 0;
#elif defined(SDL_PLATFORM_SOLARIS)
// Used for Solaris when not using gcc.
*lock = 0;

View file

@ -136,11 +136,11 @@ int SDL_GetNumAudioDrivers(void)
const char *SDL_GetAudioDriver(int index)
{
if (index >= 0 && index < SDL_GetNumAudioDrivers()) {
return deduped_bootstrap[index]->name;
CHECK_PARAM(index < 0 || index >= SDL_GetNumAudioDrivers()) {
SDL_InvalidParamError("index");
return NULL;
}
SDL_InvalidParamError("index");
return NULL;
return deduped_bootstrap[index]->name;
}
const char *SDL_GetCurrentAudioDriver(void)
@ -171,10 +171,13 @@ int SDL_GetDefaultSampleFramesFromFreq(const int freq)
int *SDL_ChannelMapDup(const int *origchmap, int channels)
{
const size_t chmaplen = sizeof (*origchmap) * channels;
int *chmap = (int *)SDL_malloc(chmaplen);
if (chmap) {
SDL_memcpy(chmap, origchmap, chmaplen);
int *chmap = NULL;
if ((channels > 0) && origchmap) {
const size_t chmaplen = sizeof (*origchmap) * channels;
chmap = (int *)SDL_malloc(chmaplen);
if (chmap) {
SDL_memcpy(chmap, origchmap, chmaplen);
}
}
return chmap;
}
@ -734,11 +737,10 @@ SDL_AudioDevice *SDL_AddAudioDevice(bool recording, const char *name, const SDL_
}
// Called when a device is removed from the system, or it fails unexpectedly, from any thread, possibly even the audio device's thread.
void SDL_AudioDeviceDisconnected(SDL_AudioDevice *device)
static void SDLCALL SDL_AudioDeviceDisconnected_OnMainThread(void *userdata)
{
if (!device) {
return;
}
SDL_AudioDevice *device = (SDL_AudioDevice *) userdata;
SDL_assert(device != NULL);
// Save off removal info in a list so we can send events for each, next
// time the event queue pumps, in case something tries to close a device
@ -808,6 +810,23 @@ void SDL_AudioDeviceDisconnected(SDL_AudioDevice *device)
UnrefPhysicalAudioDevice(device);
}
// We always ref this in SDL_AudioDeviceDisconnected(), so if multiple attempts
// to disconnect are queued, the pointer stays valid until the last one comes
// through.
UnrefPhysicalAudioDevice(device);
}
void SDL_AudioDeviceDisconnected(SDL_AudioDevice *device)
{
// lots of risk of various audio backends deadlocking because they're calling
// this while holding a backend-specific lock, which causes problems when we
// want to obtain the device lock while its audio thread is also waiting for
// that lock to be released. So just queue the work on the main thread.
if (device) {
RefPhysicalAudioDevice(device);
SDL_RunOnMainThread(SDL_AudioDeviceDisconnected_OnMainThread, device, false);
}
}
@ -1576,7 +1595,7 @@ const char *SDL_GetAudioDeviceName(SDL_AudioDeviceID devid)
bool SDL_GetAudioDeviceFormat(SDL_AudioDeviceID devid, SDL_AudioSpec *spec, int *sample_frames)
{
if (!spec) {
CHECK_PARAM(!spec) {
return SDL_InvalidParamError("spec");
}
@ -1601,9 +1620,7 @@ int *SDL_GetAudioDeviceChannelMap(SDL_AudioDeviceID devid, int *count)
SDL_AudioDevice *device = ObtainPhysicalAudioDeviceDefaultAllowed(devid);
if (device) {
channels = device->spec.channels;
if (channels > 0 && device->chmap) {
result = SDL_ChannelMapDup(device->chmap, channels);
}
result = SDL_ChannelMapDup(device->chmap, channels);
}
ReleaseAudioDevice(device);
@ -1937,7 +1954,7 @@ float SDL_GetAudioDeviceGain(SDL_AudioDeviceID devid)
bool SDL_SetAudioDeviceGain(SDL_AudioDeviceID devid, float gain)
{
if (gain < 0.0f) {
CHECK_PARAM(gain < 0.0f) {
return SDL_InvalidParamError("gain");
}
@ -1986,11 +2003,15 @@ bool SDL_BindAudioStreams(SDL_AudioDeviceID devid, SDL_AudioStream * const *stre
if (num_streams == 0) {
return true; // nothing to do
} else if (num_streams < 0) {
}
CHECK_PARAM(num_streams < 0) {
return SDL_InvalidParamError("num_streams");
} else if (!streams) {
}
CHECK_PARAM(!streams) {
return SDL_InvalidParamError("streams");
} else if (SDL_IsAudioDevicePhysical(devid)) {
}
CHECK_PARAM(SDL_IsAudioDevicePhysical(devid)) {
return SDL_SetError("Audio streams are bound to device ids from SDL_OpenAudioDevice, not raw physical devices");
}
@ -2150,7 +2171,7 @@ SDL_AudioDeviceID SDL_GetAudioStreamDevice(SDL_AudioStream *stream)
{
SDL_AudioDeviceID result = 0;
if (!stream) {
CHECK_PARAM(!stream) {
SDL_InvalidParamError("stream");
return 0;
}

View file

@ -474,10 +474,11 @@ SDL_AudioStream *SDL_CreateAudioStream(const SDL_AudioSpec *src_spec, const SDL_
SDL_PropertiesID SDL_GetAudioStreamProperties(SDL_AudioStream *stream)
{
if (!stream) {
CHECK_PARAM(!stream) {
SDL_InvalidParamError("stream");
return 0;
}
SDL_LockMutex(stream->lock);
if (stream->props == 0) {
stream->props = SDL_CreateProperties();
@ -488,9 +489,10 @@ SDL_PropertiesID SDL_GetAudioStreamProperties(SDL_AudioStream *stream)
bool SDL_SetAudioStreamGetCallback(SDL_AudioStream *stream, SDL_AudioStreamCallback callback, void *userdata)
{
if (!stream) {
CHECK_PARAM(!stream) {
return SDL_InvalidParamError("stream");
}
SDL_LockMutex(stream->lock);
stream->get_callback = callback;
stream->get_callback_userdata = userdata;
@ -500,9 +502,10 @@ bool SDL_SetAudioStreamGetCallback(SDL_AudioStream *stream, SDL_AudioStreamCallb
bool SDL_SetAudioStreamPutCallback(SDL_AudioStream *stream, SDL_AudioStreamCallback callback, void *userdata)
{
if (!stream) {
CHECK_PARAM(!stream) {
return SDL_InvalidParamError("stream");
}
SDL_LockMutex(stream->lock);
stream->put_callback = callback;
stream->put_callback_userdata = userdata;
@ -512,25 +515,27 @@ bool SDL_SetAudioStreamPutCallback(SDL_AudioStream *stream, SDL_AudioStreamCallb
bool SDL_LockAudioStream(SDL_AudioStream *stream)
{
if (!stream) {
CHECK_PARAM(!stream) {
return SDL_InvalidParamError("stream");
}
SDL_LockMutex(stream->lock);
return true;
}
bool SDL_UnlockAudioStream(SDL_AudioStream *stream)
{
if (!stream) {
CHECK_PARAM(!stream) {
return SDL_InvalidParamError("stream");
}
SDL_UnlockMutex(stream->lock);
return true;
}
bool SDL_GetAudioStreamFormat(SDL_AudioStream *stream, SDL_AudioSpec *src_spec, SDL_AudioSpec *dst_spec)
{
if (!stream) {
CHECK_PARAM(!stream) {
if (src_spec) {
SDL_zerop(src_spec);
}
@ -560,7 +565,7 @@ bool SDL_GetAudioStreamFormat(SDL_AudioStream *stream, SDL_AudioSpec *src_spec,
bool SDL_SetAudioStreamFormat(SDL_AudioStream *stream, const SDL_AudioSpec *src_spec, const SDL_AudioSpec *dst_spec)
{
if (!stream) {
CHECK_PARAM(!stream) {
return SDL_InvalidParamError("stream");
}
@ -569,21 +574,25 @@ bool SDL_SetAudioStreamFormat(SDL_AudioStream *stream, const SDL_AudioSpec *src_
// like 196608000Hz. File a bug. :P
if (src_spec) {
if (!SDL_IsSupportedAudioFormat(src_spec->format)) {
CHECK_PARAM(!SDL_IsSupportedAudioFormat(src_spec->format)) {
return SDL_InvalidParamError("src_spec->format");
} else if (!SDL_IsSupportedChannelCount(src_spec->channels)) {
}
CHECK_PARAM(!SDL_IsSupportedChannelCount(src_spec->channels)) {
return SDL_InvalidParamError("src_spec->channels");
} else if (src_spec->freq <= 0) {
}
CHECK_PARAM(src_spec->freq <= 0) {
return SDL_InvalidParamError("src_spec->freq");
}
}
if (dst_spec) {
if (!SDL_IsSupportedAudioFormat(dst_spec->format)) {
CHECK_PARAM(!SDL_IsSupportedAudioFormat(dst_spec->format)) {
return SDL_InvalidParamError("dst_spec->format");
} else if (!SDL_IsSupportedChannelCount(dst_spec->channels)) {
}
CHECK_PARAM(!SDL_IsSupportedChannelCount(dst_spec->channels)) {
return SDL_InvalidParamError("dst_spec->channels");
} else if (dst_spec->freq <= 0) {
}
CHECK_PARAM(dst_spec->freq <= 0) {
return SDL_InvalidParamError("dst_spec->freq");
}
}
@ -622,7 +631,7 @@ bool SDL_SetAudioStreamFormat(SDL_AudioStream *stream, const SDL_AudioSpec *src_
bool SetAudioStreamChannelMap(SDL_AudioStream *stream, const SDL_AudioSpec *spec, int **stream_chmap, const int *chmap, int channels, int isinput)
{
if (!stream) {
CHECK_PARAM(!stream) {
return SDL_InvalidParamError("stream");
}
@ -708,7 +717,7 @@ int *SDL_GetAudioStreamOutputChannelMap(SDL_AudioStream *stream, int *count)
float SDL_GetAudioStreamFrequencyRatio(SDL_AudioStream *stream)
{
if (!stream) {
CHECK_PARAM(!stream) {
SDL_InvalidParamError("stream");
return 0.0f;
}
@ -722,7 +731,7 @@ float SDL_GetAudioStreamFrequencyRatio(SDL_AudioStream *stream)
bool SDL_SetAudioStreamFrequencyRatio(SDL_AudioStream *stream, float freq_ratio)
{
if (!stream) {
CHECK_PARAM(!stream) {
return SDL_InvalidParamError("stream");
}
@ -745,7 +754,7 @@ bool SDL_SetAudioStreamFrequencyRatio(SDL_AudioStream *stream, float freq_ratio)
float SDL_GetAudioStreamGain(SDL_AudioStream *stream)
{
if (!stream) {
CHECK_PARAM(!stream) {
SDL_InvalidParamError("stream");
return -1.0f;
}
@ -759,9 +768,10 @@ float SDL_GetAudioStreamGain(SDL_AudioStream *stream)
bool SDL_SetAudioStreamGain(SDL_AudioStream *stream, float gain)
{
if (!stream) {
CHECK_PARAM(!stream) {
return SDL_InvalidParamError("stream");
} else if (gain < 0.0f) {
}
CHECK_PARAM(gain < 0.0f) {
return SDL_InvalidParamError("gain");
}
@ -847,13 +857,17 @@ static void SDLCALL FreeAllocatedAudioBuffer(void *userdata, const void *buf, in
bool SDL_PutAudioStreamData(SDL_AudioStream *stream, const void *buf, int len)
{
if (!stream) {
CHECK_PARAM(!stream) {
return SDL_InvalidParamError("stream");
} else if (!buf) {
}
CHECK_PARAM(!buf) {
return SDL_InvalidParamError("buf");
} else if (len < 0) {
}
CHECK_PARAM(len < 0) {
return SDL_InvalidParamError("len");
} else if (len == 0) {
}
if (len == 0) {
return true; // nothing to do.
}
@ -965,13 +979,17 @@ static void InterleaveAudioChannels(void *output, const void * const *channel_bu
bool SDL_PutAudioStreamPlanarData(SDL_AudioStream *stream, const void * const *channel_buffers, int num_channels, int num_samples)
{
if (!stream) {
CHECK_PARAM(!stream) {
return SDL_InvalidParamError("stream");
} else if (!channel_buffers) {
}
CHECK_PARAM(!channel_buffers) {
return SDL_InvalidParamError("channel_buffers");
} else if (num_samples < 0) {
}
CHECK_PARAM(num_samples < 0) {
return SDL_InvalidParamError("num_samples");
} else if (num_samples == 0) {
}
if (num_samples == 0) {
return true; // nothing to do.
}
@ -1039,13 +1057,17 @@ static void SDLCALL DontFreeThisAudioBuffer(void *userdata, const void *buf, int
bool SDL_PutAudioStreamDataNoCopy(SDL_AudioStream *stream, const void *buf, int len, SDL_AudioStreamDataCompleteCallback callback, void *userdata)
{
if (!stream) {
CHECK_PARAM(!stream) {
return SDL_InvalidParamError("stream");
} else if (!buf) {
}
CHECK_PARAM(!buf) {
return SDL_InvalidParamError("buf");
} else if (len < 0) {
}
CHECK_PARAM(len < 0) {
return SDL_InvalidParamError("len");
} else if (len == 0) {
}
if (len == 0) {
if (callback) {
callback(userdata, buf, len);
}
@ -1057,7 +1079,7 @@ bool SDL_PutAudioStreamDataNoCopy(SDL_AudioStream *stream, const void *buf, int
bool SDL_FlushAudioStream(SDL_AudioStream *stream)
{
if (!stream) {
CHECK_PARAM(!stream) {
return SDL_InvalidParamError("stream");
}
@ -1320,16 +1342,20 @@ int SDL_GetAudioStreamDataAdjustGain(SDL_AudioStream *stream, void *voidbuf, int
SDL_Log("AUDIOSTREAM: want to get %d converted bytes", len);
#endif
if (!stream) {
CHECK_PARAM(!stream) {
SDL_InvalidParamError("stream");
return -1;
} else if (!buf) {
}
CHECK_PARAM(!buf) {
SDL_InvalidParamError("buf");
return -1;
} else if (len < 0) {
}
CHECK_PARAM(len < 0) {
SDL_InvalidParamError("len");
return -1;
} else if (len == 0) {
}
if (len == 0) {
return 0; // nothing to do.
}
@ -1427,7 +1453,7 @@ int SDL_GetAudioStreamData(SDL_AudioStream *stream, void *voidbuf, int len)
// number of converted/resampled bytes available for output
int SDL_GetAudioStreamAvailable(SDL_AudioStream *stream)
{
if (!stream) {
CHECK_PARAM(!stream) {
SDL_InvalidParamError("stream");
return -1;
}
@ -1453,7 +1479,7 @@ int SDL_GetAudioStreamAvailable(SDL_AudioStream *stream)
// number of sample frames that are currently queued as input.
int SDL_GetAudioStreamQueued(SDL_AudioStream *stream)
{
if (!stream) {
CHECK_PARAM(!stream) {
SDL_InvalidParamError("stream");
return -1;
}
@ -1470,7 +1496,7 @@ int SDL_GetAudioStreamQueued(SDL_AudioStream *stream)
bool SDL_ClearAudioStream(SDL_AudioStream *stream)
{
if (!stream) {
CHECK_PARAM(!stream) {
return SDL_InvalidParamError("stream");
}
@ -1522,13 +1548,16 @@ bool SDL_ConvertAudioSamples(const SDL_AudioSpec *src_spec, const Uint8 *src_dat
*dst_len = 0;
}
if (!src_data) {
CHECK_PARAM(!src_data) {
return SDL_InvalidParamError("src_data");
} else if (src_len < 0) {
}
CHECK_PARAM(src_len < 0) {
return SDL_InvalidParamError("src_len");
} else if (!dst_data) {
}
CHECK_PARAM(!dst_data) {
return SDL_InvalidParamError("dst_data");
} else if (!dst_len) {
}
CHECK_PARAM(!dst_len) {
return SDL_InvalidParamError("dst_len");
}

View file

@ -1775,6 +1775,7 @@ static bool WaveLoad(SDL_IOStream *src, WaveFile *file, SDL_AudioSpec *spec, Uin
int result;
Uint32 chunkcount = 0;
Uint32 chunkcountlimit = 10000;
const Sint64 flen = SDL_GetIOSize(src); // this might be -1 if the IOStream can't determine the total size.
const char *hint;
Sint64 RIFFstart, RIFFend, lastchunkpos;
bool RIFFlengthknown = false;
@ -1883,6 +1884,14 @@ static bool WaveLoad(SDL_IOStream *src, WaveFile *file, SDL_AudioSpec *spec, Uin
fmtchunk = *chunk;
}
} else if (chunk->fourcc == DATA) {
/* If the data chunk is bigger than the file, it might be corrupt
or the file is truncated. Try to recover by clamping the file
size. This also means a malicious file can't allocate 4 gigabytes
for the chunks without actually supplying a 4 gigabyte file. */
if ((flen > 0) && ((chunk->position + chunk->length) > flen)) {
chunk->length = (Uint32) (flen - chunk->position);
}
/* Only use the first data chunk. Handling the wavl list madness
* may require a different approach.
*/
@ -2092,16 +2101,19 @@ bool SDL_LoadWAV_IO(SDL_IOStream *src, bool closeio, SDL_AudioSpec *spec, Uint8
}
// Make sure we are passed a valid data source
if (!src) {
CHECK_PARAM(!src) {
SDL_InvalidParamError("src");
goto done;
} else if (!spec) {
}
CHECK_PARAM(!spec) {
SDL_InvalidParamError("spec");
goto done;
} else if (!audio_buf) {
}
CHECK_PARAM(!audio_buf) {
SDL_InvalidParamError("audio_buf");
goto done;
} else if (!audio_len) {
}
CHECK_PARAM(!audio_len) {
SDL_InvalidParamError("audio_len");
goto done;
}

View file

@ -40,16 +40,16 @@ static bool SupportsIMMDevice = false;
// DirectX function pointers for audio
static SDL_SharedObject *DSoundDLL = NULL;
typedef HRESULT(WINAPI *fnDirectSoundCreate8)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN);
typedef HRESULT(WINAPI *fnDirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID);
typedef HRESULT(WINAPI *fnDirectSoundCaptureCreate8)(LPCGUID, LPDIRECTSOUNDCAPTURE8 *, LPUNKNOWN);
typedef HRESULT(WINAPI *fnDirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW, LPVOID);
typedef HRESULT(WINAPI *fnGetDeviceID)(LPCGUID, LPGUID);
static fnDirectSoundCreate8 pDirectSoundCreate8 = NULL;
static fnDirectSoundEnumerateW pDirectSoundEnumerateW = NULL;
static fnDirectSoundCaptureCreate8 pDirectSoundCaptureCreate8 = NULL;
static fnDirectSoundCaptureEnumerateW pDirectSoundCaptureEnumerateW = NULL;
static fnGetDeviceID pGetDeviceID = NULL;
typedef HRESULT (WINAPI *pfnDirectSoundCreate8)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN);
typedef HRESULT (WINAPI *pfnDirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID);
typedef HRESULT (WINAPI *pfnDirectSoundCaptureCreate8)(LPCGUID, LPDIRECTSOUNDCAPTURE8 *, LPUNKNOWN);
typedef HRESULT (WINAPI *pfnDirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW, LPVOID);
typedef HRESULT (WINAPI *pfnGetDeviceID)(LPCGUID, LPGUID);
static pfnDirectSoundCreate8 pDirectSoundCreate8 = NULL;
static pfnDirectSoundEnumerateW pDirectSoundEnumerateW = NULL;
static pfnDirectSoundCaptureCreate8 pDirectSoundCaptureCreate8 = NULL;
static pfnDirectSoundCaptureEnumerateW pDirectSoundCaptureEnumerateW = NULL;
static pfnGetDeviceID pGetDeviceID = NULL;
#include <initguid.h>
DEFINE_GUID(SDL_DSDEVID_DefaultPlayback, 0xdef00000, 0x9c6d, 0x47ed, 0xaa, 0xf1, 0x4d, 0xda, 0x8f, 0x2b, 0x5c, 0x03);
@ -85,7 +85,7 @@ static bool DSOUND_Load(void)
// Now make sure we have DirectX 8 or better...
#define DSOUNDLOAD(f) \
{ \
p##f = (fn##f)SDL_LoadFunction(DSoundDLL, #f); \
p##f = (pfn##f)SDL_LoadFunction(DSoundDLL, #f); \
if (!p##f) \
loaded = false; \
}

View file

@ -155,11 +155,8 @@ static bool EMSCRIPTENAUDIO_OpenDevice(SDL_AudioDevice *device)
Module['SDL3'] = {};
}
var SDL3 = Module['SDL3'];
if (!$0) {
SDL3.audio_playback = {};
} else {
SDL3.audio_recording = {};
}
SDL3.audio_playback = {};
SDL3.audio_recording = {};
if (!SDL3.audioContext) {
if (typeof(AudioContext) !== 'undefined') {

View file

@ -45,8 +45,8 @@
// handle to Avrt.dll--Vista and later!--for flagging the callback thread as "Pro Audio" (low latency).
static HMODULE libavrt = NULL;
typedef HANDLE(WINAPI *pfnAvSetMmThreadCharacteristicsW)(LPCWSTR, LPDWORD);
typedef BOOL(WINAPI *pfnAvRevertMmThreadCharacteristics)(HANDLE);
typedef HANDLE (WINAPI *pfnAvSetMmThreadCharacteristicsW)(LPCWSTR, LPDWORD);
typedef BOOL (WINAPI *pfnAvRevertMmThreadCharacteristics)(HANDLE);
static pfnAvSetMmThreadCharacteristicsW pAvSetMmThreadCharacteristicsW = NULL;
static pfnAvRevertMmThreadCharacteristics pAvRevertMmThreadCharacteristics = NULL;
@ -164,21 +164,10 @@ bool WASAPI_ProxyToManagementThread(ManagementThreadTask task, void *userdata, b
return true; // successfully added (and possibly executed)!
}
static bool mgmtthrtask_AudioDeviceDisconnected(void *userdata)
{
SDL_AudioDevice *device = (SDL_AudioDevice *) userdata;
SDL_AudioDeviceDisconnected(device);
UnrefPhysicalAudioDevice(device); // make sure this lived until the task completes.
return true;
}
static void AudioDeviceDisconnected(SDL_AudioDevice *device)
{
// don't wait on this, IMMDevice's own thread needs to return or everything will deadlock.
if (device) {
RefPhysicalAudioDevice(device); // make sure this lives until the task completes.
WASAPI_ProxyToManagementThread(mgmtthrtask_AudioDeviceDisconnected, device, NULL);
}
WASAPI_DisconnectDevice(device);
}
static bool mgmtthrtask_DefaultAudioDeviceChanged(void *userdata)
@ -351,19 +340,11 @@ static void WASAPI_DetectDevices(SDL_AudioDevice **default_playback, SDL_AudioDe
WASAPI_ProxyToManagementThread(mgmtthrtask_DetectDevices, &data, &rc);
}
static bool mgmtthrtask_DisconnectDevice(void *userdata)
{
SDL_AudioDevice *device = (SDL_AudioDevice *) userdata;
SDL_AudioDeviceDisconnected(device);
UnrefPhysicalAudioDevice(device);
return true;
}
void WASAPI_DisconnectDevice(SDL_AudioDevice *device)
{
if (SDL_CompareAndSwapAtomicInt(&device->hidden->device_disconnecting, 0, 1)) {
RefPhysicalAudioDevice(device); // will unref when the task ends.
WASAPI_ProxyToManagementThread(mgmtthrtask_DisconnectDevice, device, NULL);
// don't block in here; IMMDevice's own thread needs to return or everything will deadlock.
if (device->hidden && SDL_CompareAndSwapAtomicInt(&device->hidden->device_disconnecting, 0, 1)) {
SDL_AudioDeviceDisconnected(device); // this proxies the work to the main thread now, so no point in proxying to the management thread.
}
}

View file

@ -69,11 +69,11 @@ int SDL_GetNumCameraDrivers(void)
const char *SDL_GetCameraDriver(int index)
{
if (index >= 0 && index < SDL_GetNumCameraDrivers()) {
return bootstrap[index]->name;
CHECK_PARAM(index < 0 || index >= SDL_GetNumCameraDrivers()) {
SDL_InvalidParamError("index");
return NULL;
}
SDL_InvalidParamError("index");
return NULL;
return bootstrap[index]->name;
}
const char *SDL_GetCurrentCameraDriver(void)
@ -657,9 +657,10 @@ bool SDL_GetCameraFormat(SDL_Camera *camera, SDL_CameraSpec *spec)
{
bool result;
if (!camera) {
CHECK_PARAM(!camera) {
return SDL_InvalidParamError("camera");
} else if (!spec) {
}
CHECK_PARAM(!spec) {
return SDL_InvalidParamError("spec");
}
@ -1255,7 +1256,7 @@ SDL_Surface *SDL_AcquireCameraFrame(SDL_Camera *camera, Uint64 *timestampNS)
*timestampNS = 0;
}
if (!camera) {
CHECK_PARAM(!camera) {
SDL_InvalidParamError("camera");
return NULL;
}
@ -1340,49 +1341,55 @@ void SDL_ReleaseCameraFrame(SDL_Camera *camera, SDL_Surface *frame)
SDL_CameraID SDL_GetCameraID(SDL_Camera *camera)
{
SDL_CameraID result = 0;
if (!camera) {
SDL_CameraID result;
CHECK_PARAM(!camera) {
SDL_InvalidParamError("camera");
} else {
SDL_Camera *device = camera; // currently there's no separation between physical and logical device.
ObtainPhysicalCameraObj(device);
result = device->instance_id;
ReleaseCamera(device);
return 0;
}
SDL_Camera *device = camera; // currently there's no separation between physical and logical device.
ObtainPhysicalCameraObj(device);
result = device->instance_id;
ReleaseCamera(device);
return result;
}
SDL_PropertiesID SDL_GetCameraProperties(SDL_Camera *camera)
{
SDL_PropertiesID result = 0;
if (!camera) {
SDL_PropertiesID result;
CHECK_PARAM(!camera) {
SDL_InvalidParamError("camera");
} else {
SDL_Camera *device = camera; // currently there's no separation between physical and logical device.
ObtainPhysicalCameraObj(device);
if (device->props == 0) {
device->props = SDL_CreateProperties();
}
result = device->props;
ReleaseCamera(device);
return 0;
}
SDL_Camera *device = camera; // currently there's no separation between physical and logical device.
ObtainPhysicalCameraObj(device);
if (device->props == 0) {
device->props = SDL_CreateProperties();
}
result = device->props;
ReleaseCamera(device);
return result;
}
SDL_CameraPermissionState SDL_GetCameraPermissionState(SDL_Camera *camera)
{
SDL_CameraPermissionState result;
if (!camera) {
CHECK_PARAM(!camera) {
SDL_InvalidParamError("camera");
result = SDL_CAMERA_PERMISSION_STATE_DENIED;
} else {
SDL_Camera *device = camera; // currently there's no separation between physical and logical device.
ObtainPhysicalCameraObj(device);
result = device->permission;
ReleaseCamera(device);
return SDL_CAMERA_PERMISSION_STATE_DENIED;
}
SDL_Camera *device = camera; // currently there's no separation between physical and logical device.
ObtainPhysicalCameraObj(device);
result = device->permission;
ReleaseCamera(device);
return result;
}

View file

@ -324,18 +324,18 @@ static const GUID *SDLFmtToMFVidFmtGuid(SDL_PixelFormat format)
// mf.dll ...
static HMODULE libmf = NULL;
typedef HRESULT(WINAPI *pfnMFEnumDeviceSources)(IMFAttributes *,IMFActivate ***,UINT32 *);
typedef HRESULT(WINAPI *pfnMFCreateDeviceSource)(IMFAttributes *, IMFMediaSource **);
typedef HRESULT (WINAPI *pfnMFEnumDeviceSources)(IMFAttributes *,IMFActivate ***,UINT32 *);
typedef HRESULT (WINAPI *pfnMFCreateDeviceSource)(IMFAttributes *, IMFMediaSource **);
static pfnMFEnumDeviceSources pMFEnumDeviceSources = NULL;
static pfnMFCreateDeviceSource pMFCreateDeviceSource = NULL;
// mfplat.dll ...
static HMODULE libmfplat = NULL;
typedef HRESULT(WINAPI *pfnMFStartup)(ULONG, DWORD);
typedef HRESULT(WINAPI *pfnMFShutdown)(void);
typedef HRESULT(WINAPI *pfnMFCreateAttributes)(IMFAttributes **, UINT32);
typedef HRESULT(WINAPI *pfnMFCreateMediaType)(IMFMediaType **);
typedef HRESULT(WINAPI *pfnMFGetStrideForBitmapInfoHeader)(DWORD, DWORD, LONG *);
typedef HRESULT (WINAPI *pfnMFStartup)(ULONG, DWORD);
typedef HRESULT (WINAPI *pfnMFShutdown)(void);
typedef HRESULT (WINAPI *pfnMFCreateAttributes)(IMFAttributes **, UINT32);
typedef HRESULT (WINAPI *pfnMFCreateMediaType)(IMFMediaType **);
typedef HRESULT (WINAPI *pfnMFGetStrideForBitmapInfoHeader)(DWORD, DWORD, LONG *);
static pfnMFStartup pMFStartup = NULL;
static pfnMFShutdown pMFShutdown = NULL;
@ -345,7 +345,7 @@ static pfnMFGetStrideForBitmapInfoHeader pMFGetStrideForBitmapInfoHeader = NULL;
// mfreadwrite.dll ...
static HMODULE libmfreadwrite = NULL;
typedef HRESULT(WINAPI *pfnMFCreateSourceReaderFromMediaSource)(IMFMediaSource *, IMFAttributes *, IMFSourceReader **);
typedef HRESULT (WINAPI *pfnMFCreateSourceReaderFromMediaSource)(IMFMediaSource *, IMFAttributes *, IMFSourceReader **);
static pfnMFCreateSourceReaderFromMediaSource pMFCreateSourceReaderFromMediaSource = NULL;

View file

@ -20,18 +20,18 @@
*/
#include "SDL_internal.h"
#include "SDL_core_unsupported.h"
#ifndef SDL_VIDEO_DRIVER_X11
SDL_DECLSPEC void SDLCALL SDL_SetX11EventHook(SDL_X11EventHook callback, void *userdata);
void SDL_SetX11EventHook(SDL_X11EventHook callback, void *userdata)
{
}
#endif
#endif /* !SDL_VIDEO_DRIVER_X11 */
#ifndef SDL_PLATFORM_LINUX
SDL_DECLSPEC bool SDLCALL SDL_SetLinuxThreadPriority(Sint64 threadID, int priority);
bool SDL_SetLinuxThreadPriority(Sint64 threadID, int priority)
{
(void)threadID;
@ -39,7 +39,6 @@ bool SDL_SetLinuxThreadPriority(Sint64 threadID, int priority)
return SDL_Unsupported();
}
SDL_DECLSPEC bool SDLCALL SDL_SetLinuxThreadPriorityAndPolicy(Sint64 threadID, int sdlPriority, int schedPolicy);
bool SDL_SetLinuxThreadPriorityAndPolicy(Sint64 threadID, int sdlPriority, int schedPolicy)
{
(void)threadID;
@ -48,37 +47,32 @@ bool SDL_SetLinuxThreadPriorityAndPolicy(Sint64 threadID, int sdlPriority, int s
return SDL_Unsupported();
}
#endif
#endif /* !SDL_PLATFORM_LINUX */
#ifndef SDL_PLATFORM_GDK
SDL_DECLSPEC void SDLCALL SDL_GDKSuspendComplete(void);
void SDL_GDKSuspendComplete(void)
{
SDL_Unsupported();
}
SDL_DECLSPEC bool SDLCALL SDL_GetGDKDefaultUser(void *outUserHandle); /* XUserHandle *outUserHandle */
bool SDL_GetGDKDefaultUser(void *outUserHandle)
bool SDL_GetGDKDefaultUser(XUserHandle *outUserHandle)
{
return SDL_Unsupported();
}
SDL_DECLSPEC void SDLCALL SDL_GDKSuspendGPU(SDL_GPUDevice *device);
void SDL_GDKSuspendGPU(SDL_GPUDevice *device)
{
}
SDL_DECLSPEC void SDLCALL SDL_GDKResumeGPU(SDL_GPUDevice *device);
void SDL_GDKResumeGPU(SDL_GPUDevice *device)
{
}
#endif
#endif /* !SDL_PLATFORM_GDK */
#if !defined(SDL_PLATFORM_WINDOWS)
SDL_DECLSPEC bool SDLCALL SDL_RegisterApp(const char *name, Uint32 style, void *hInst);
bool SDL_RegisterApp(const char *name, Uint32 style, void *hInst)
{
(void)name;
@ -87,7 +81,6 @@ bool SDL_RegisterApp(const char *name, Uint32 style, void *hInst)
return SDL_Unsupported();
}
SDL_DECLSPEC void SDLCALL SDL_SetWindowsMessageHook(void *callback, void *userdata); // SDL_WindowsMessageHook callback
void SDL_SetWindowsMessageHook(void *callback, void *userdata)
{
(void)callback;
@ -95,30 +88,26 @@ void SDL_SetWindowsMessageHook(void *callback, void *userdata)
SDL_Unsupported();
}
SDL_DECLSPEC void SDLCALL SDL_UnregisterApp(void);
void SDL_UnregisterApp(void)
{
SDL_Unsupported();
}
#endif
#endif /* !SDL_PLATFORM_WINDOWS */
#ifndef SDL_PLATFORM_ANDROID
SDL_DECLSPEC void SDLCALL SDL_SendAndroidBackButton(void);
void SDL_SendAndroidBackButton(void)
{
SDL_Unsupported();
}
SDL_DECLSPEC void * SDLCALL SDL_GetAndroidActivity(void);
void *SDL_GetAndroidActivity(void)
{
SDL_Unsupported();
return NULL;
}
SDL_DECLSPEC const char * SDLCALL SDL_GetAndroidCachePath(void);
const char *SDL_GetAndroidCachePath(void)
{
SDL_Unsupported();
@ -126,35 +115,29 @@ const char *SDL_GetAndroidCachePath(void)
}
SDL_DECLSPEC const char * SDLCALL SDL_GetAndroidExternalStoragePath(void);
const char *SDL_GetAndroidExternalStoragePath(void)
{
SDL_Unsupported();
return NULL;
}
SDL_DECLSPEC Uint32 SDLCALL SDL_GetAndroidExternalStorageState(void);
Uint32 SDL_GetAndroidExternalStorageState(void)
{
SDL_Unsupported();
return 0;
}
SDL_DECLSPEC const char * SDLCALL SDL_GetAndroidInternalStoragePath(void);
const char *SDL_GetAndroidInternalStoragePath(void)
{
SDL_Unsupported();
return NULL;
}
SDL_DECLSPEC void * SDLCALL SDL_GetAndroidJNIEnv(void);
void *SDL_GetAndroidJNIEnv(void)
{
SDL_Unsupported();
return NULL;
}
typedef void (SDLCALL *SDL_RequestAndroidPermissionCallback)(void *userdata, const char *permission, bool granted);
SDL_DECLSPEC bool SDLCALL SDL_RequestAndroidPermission(const char *permission, SDL_RequestAndroidPermissionCallback cb, void *userdata);
bool SDL_RequestAndroidPermission(const char *permission, SDL_RequestAndroidPermissionCallback cb, void *userdata)
{
(void)permission;
@ -163,7 +146,6 @@ bool SDL_RequestAndroidPermission(const char *permission, SDL_RequestAndroidPerm
return SDL_Unsupported();
}
SDL_DECLSPEC bool SDLCALL SDL_SendAndroidMessage(Uint32 command, int param);
bool SDL_SendAndroidMessage(Uint32 command, int param)
{
(void)command;
@ -171,7 +153,6 @@ bool SDL_SendAndroidMessage(Uint32 command, int param)
return SDL_Unsupported();
}
SDL_DECLSPEC bool SDLCALL SDL_ShowAndroidToast(const char *message, int duration, int gravity, int xoffset, int yoffset);
bool SDL_ShowAndroidToast(const char *message, int duration, int gravity, int xoffset, int yoffset)
{
(void)message;
@ -182,28 +163,24 @@ bool SDL_ShowAndroidToast(const char *message, int duration, int gravity, int xo
return SDL_Unsupported();
}
SDL_DECLSPEC int SDLCALL SDL_GetAndroidSDKVersion(void);
int SDL_GetAndroidSDKVersion(void)
{
return SDL_Unsupported();
}
SDL_DECLSPEC bool SDLCALL SDL_IsChromebook(void);
bool SDL_IsChromebook(void)
{
SDL_Unsupported();
return false;
}
SDL_DECLSPEC bool SDLCALL SDL_IsDeXMode(void);
bool SDL_IsDeXMode(void)
{
SDL_Unsupported();
return false;
}
SDL_DECLSPEC Sint32 SDLCALL JNI_OnLoad(void *vm, void *reserved);
Sint32 JNI_OnLoad(void *vm, void *reserved)
Sint32 JNI_OnLoad(JavaVM *vm, void *reserved)
{
(void)vm;
(void)reserved;

View file

@ -0,0 +1,65 @@
/*
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.
*/
#ifndef SDL_VIDEO_DRIVER_X11
extern SDL_DECLSPEC void SDLCALL SDL_SetX11EventHook(SDL_X11EventHook callback, void *userdata);
#endif
#ifndef SDL_PLATFORM_LINUX
extern SDL_DECLSPEC bool SDLCALL SDL_SetLinuxThreadPriority(Sint64 threadID, int priority);
extern SDL_DECLSPEC bool SDLCALL SDL_SetLinuxThreadPriorityAndPolicy(Sint64 threadID, int sdlPriority, int schedPolicy);
#endif
#if !defined(SDL_PLATFORM_GDK)
typedef struct XUserHandle XUserHandle;
extern SDL_DECLSPEC void SDLCALL SDL_GDKSuspendComplete(void);
extern SDL_DECLSPEC bool SDLCALL SDL_GetGDKDefaultUser(XUserHandle *outUserHandle);
extern SDL_DECLSPEC void SDLCALL SDL_GDKSuspendGPU(SDL_GPUDevice *device);
extern SDL_DECLSPEC void SDLCALL SDL_GDKResumeGPU(SDL_GPUDevice *device);
#endif /* !SDL_PLATFORM_GDK */
#if !defined(SDL_PLATFORM_WINDOWS)
extern SDL_DECLSPEC bool SDLCALL SDL_RegisterApp(const char *name, Uint32 style, void *hInst);
extern SDL_DECLSPEC void SDLCALL SDL_SetWindowsMessageHook(void *callback, void *userdata);
extern SDL_DECLSPEC void SDLCALL SDL_UnregisterApp(void);
#endif /* !SDL_PLATFORM_WINDOWS */
#if !defined(SDL_PLATFORM_ANDROID)
typedef void *SDL_RequestAndroidPermissionCallback;
typedef void *JavaVM;
extern SDL_DECLSPEC void SDLCALL SDL_SendAndroidBackButton(void);
extern SDL_DECLSPEC void * SDLCALL SDL_GetAndroidActivity(void);
extern SDL_DECLSPEC const char * SDLCALL SDL_GetAndroidCachePath(void);
extern SDL_DECLSPEC const char * SDLCALL SDL_GetAndroidExternalStoragePath(void);
extern SDL_DECLSPEC Uint32 SDLCALL SDL_GetAndroidExternalStorageState(void);
extern SDL_DECLSPEC const char * SDLCALL SDL_GetAndroidInternalStoragePath(void);
extern SDL_DECLSPEC void * SDLCALL SDL_GetAndroidJNIEnv(void);
extern SDL_DECLSPEC bool SDLCALL SDL_RequestAndroidPermission(const char *permission, SDL_RequestAndroidPermissionCallback cb, void *userdata);
extern SDL_DECLSPEC bool SDLCALL SDL_SendAndroidMessage(Uint32 command, int param);
extern SDL_DECLSPEC bool SDLCALL SDL_ShowAndroidToast(const char *message, int duration, int gravity, int xoffset, int yoffset);
extern SDL_DECLSPEC int SDLCALL SDL_GetAndroidSDKVersion(void);
extern SDL_DECLSPEC bool SDLCALL SDL_IsChromebook(void);
extern SDL_DECLSPEC bool SDLCALL SDL_IsDeXMode(void);
extern SDL_DECLSPEC Sint32 SDLCALL JNI_OnLoad(JavaVM *vm, void *reserved);
#endif /* !SDL_PLATFORM_ANDROID */

View file

@ -198,7 +198,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeFileDialog)(
static JNINativeMethod SDLActivity_tab[] = {
{ "nativeGetVersion", "()Ljava/lang/String;", SDL_JAVA_INTERFACE(nativeGetVersion) },
{ "nativeSetupJNI", "()I", SDL_JAVA_INTERFACE(nativeSetupJNI) },
{ "nativeSetupJNI", "()V", SDL_JAVA_INTERFACE(nativeSetupJNI) },
{ "nativeInitMainThread", "()V", SDL_JAVA_INTERFACE(nativeInitMainThread) },
{ "nativeCleanupMainThread", "()V", SDL_JAVA_INTERFACE(nativeCleanupMainThread) },
{ "nativeRunMain", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)I", SDL_JAVA_INTERFACE(nativeRunMain) },
@ -265,7 +265,7 @@ JNIEXPORT void JNICALL
jint device_id);
static JNINativeMethod SDLAudioManager_tab[] = {
{ "nativeSetupJNI", "()I", SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI) },
{ "nativeSetupJNI", "()V", SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI) },
{ "nativeAddAudioDevice", "(ZLjava/lang/String;I)V", SDL_JAVA_AUDIO_INTERFACE(nativeAddAudioDevice) },
{ "nativeRemoveAudioDevice", "(ZI)V", SDL_JAVA_AUDIO_INTERFACE(nativeRemoveAudioDevice) }
};
@ -308,7 +308,7 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic)(
jint device_id);
static JNINativeMethod SDLControllerManager_tab[] = {
{ "nativeSetupJNI", "()I", SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI) },
{ "nativeSetupJNI", "()V", SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI) },
{ "onNativePadDown", "(II)Z", SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown) },
{ "onNativePadUp", "(II)Z", SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp) },
{ "onNativeJoy", "(IIF)V", SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoy) },
@ -635,7 +635,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl
midClipboardSetText = (*env)->GetStaticMethodID(env, mActivityClass, "clipboardSetText", "(Ljava/lang/String;)V");
midCreateCustomCursor = (*env)->GetStaticMethodID(env, mActivityClass, "createCustomCursor", "([IIIII)I");
midDestroyCustomCursor = (*env)->GetStaticMethodID(env, mActivityClass, "destroyCustomCursor", "(I)V");
midGetContext = (*env)->GetStaticMethodID(env, mActivityClass, "getContext", "()Landroid/content/Context;");
midGetContext = (*env)->GetStaticMethodID(env, mActivityClass, "getContext", "()Landroid/app/Activity;");
midGetManifestEnvironmentVariables = (*env)->GetStaticMethodID(env, mActivityClass, "getManifestEnvironmentVariables", "()Z");
midGetNativeSurface = (*env)->GetStaticMethodID(env, mActivityClass, "getNativeSurface", "()Landroid/view/Surface;");
midInitTouch = (*env)->GetStaticMethodID(env, mActivityClass, "initTouch", "()V");
@ -2113,7 +2113,7 @@ void Android_JNI_HapticStop(int device_id)
bool SDL_SendAndroidMessage(Uint32 command, int param)
{
if (command < 0x8000) {
CHECK_PARAM(command < 0x8000) {
return SDL_InvalidParamError("command");
}
return Android_JNI_SendMessage(command, param);
@ -2227,7 +2227,7 @@ bool Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *b
mid = (*env)->GetMethodID(env, clazz,
"messageboxShowMessageBox", "(ILjava/lang/String;Ljava/lang/String;[I[I[Ljava/lang/String;[I)I");
*buttonID = (*env)->CallIntMethod(env, context, mid,
messageboxdata->flags,
(jint)messageboxdata->flags,
title,
message,
button_flags,
@ -2481,7 +2481,7 @@ const char *SDL_GetAndroidCachePath(void)
// fileObj = context.getExternalFilesDir();
mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context),
"getCacheDir", "()Ljava/io/File;");
fileObject = (*env)->CallObjectMethod(env, context, mid, NULL);
fileObject = (*env)->CallObjectMethod(env, context, mid);
if (!fileObject) {
SDL_SetError("Couldn't get cache directory");
LocalReferenceHolder_Cleanup(&refs);

View file

@ -322,10 +322,6 @@ void SDL_EVDEV_Poll(void)
return;
}
#ifdef SDL_USE_LIBUDEV
SDL_UDEV_Poll();
#endif
SDL_EVDEV_kbd_update(_this->kbd);
mouse = SDL_GetMouse();
@ -612,14 +608,14 @@ static bool SDL_EVDEV_init_keyboard(SDL_evdevlist_item *item, int udev_class)
name[0] = '\0';
ioctl(item->fd, EVIOCGNAME(sizeof(name)), name);
SDL_AddKeyboard((SDL_KeyboardID)item->fd, name, true);
SDL_AddKeyboard((SDL_KeyboardID)item->fd, name);
return true;
}
static void SDL_EVDEV_destroy_keyboard(SDL_evdevlist_item *item)
{
SDL_RemoveKeyboard((SDL_KeyboardID)item->fd, true);
SDL_RemoveKeyboard((SDL_KeyboardID)item->fd);
}
static bool SDL_EVDEV_init_mouse(SDL_evdevlist_item *item, int udev_class)
@ -631,7 +627,7 @@ static bool SDL_EVDEV_init_mouse(SDL_evdevlist_item *item, int udev_class)
name[0] = '\0';
ioctl(item->fd, EVIOCGNAME(sizeof(name)), name);
SDL_AddMouse((SDL_MouseID)item->fd, name, true);
SDL_AddMouse((SDL_MouseID)item->fd, name);
ret = ioctl(item->fd, EVIOCGABS(ABS_X), &abs_info);
if (ret < 0) {
@ -656,7 +652,7 @@ static bool SDL_EVDEV_init_mouse(SDL_evdevlist_item *item, int udev_class)
static void SDL_EVDEV_destroy_mouse(SDL_evdevlist_item *item)
{
SDL_RemoveMouse((SDL_MouseID)item->fd, true);
SDL_RemoveMouse((SDL_MouseID)item->fd);
}
static bool SDL_EVDEV_init_touchscreen(SDL_evdevlist_item *item, int udev_class)

View file

@ -120,8 +120,6 @@ bool DBUS_ApplyWindowProgress(SDL_VideoDevice *_this, SDL_Window *window)
const char *progress_visible_str = "progress-visible";
const char *progress_str = "progress";
int dbus_type_boolean_str = DBUS_TYPE_BOOLEAN;
int dbus_type_double_str = DBUS_TYPE_DOUBLE;
const int progress_visible = ShouldShowProgress(window->progress_state);
double progress = (double)window->progress_value;
@ -134,14 +132,14 @@ bool DBUS_ApplyWindowProgress(SDL_VideoDevice *_this, SDL_Window *window)
// Set progress visible property
dbus->message_iter_open_container(&props, DBUS_TYPE_DICT_ENTRY, NULL, &key_it);
dbus->message_iter_append_basic(&key_it, DBUS_TYPE_STRING, &progress_visible_str); // Append progress-visible key data
dbus->message_iter_open_container(&key_it, DBUS_TYPE_VARIANT, (const char *)&dbus_type_boolean_str, &value_it);
dbus->message_iter_open_container(&key_it, DBUS_TYPE_VARIANT, "b", &value_it);
dbus->message_iter_append_basic(&value_it, DBUS_TYPE_BOOLEAN, &progress_visible); // Append progress-visible value data
dbus->message_iter_close_container(&key_it, &value_it);
dbus->message_iter_close_container(&props, &key_it);
// Set progress value property
dbus->message_iter_open_container(&props, DBUS_TYPE_DICT_ENTRY, NULL, &key_it);
dbus->message_iter_append_basic(&key_it, DBUS_TYPE_STRING, &progress_str); // Append progress key data
dbus->message_iter_open_container(&key_it, DBUS_TYPE_VARIANT, (const char *)&dbus_type_double_str, &value_it);
dbus->message_iter_open_container(&key_it, DBUS_TYPE_VARIANT, "d", &value_it);
dbus->message_iter_append_basic(&value_it, DBUS_TYPE_DOUBLE, &progress); // Append progress value data
dbus->message_iter_close_container(&key_it, &value_it);
dbus->message_iter_close_container(&props, &key_it);

View file

@ -433,7 +433,7 @@ static SDL_WSCONS_input_data *SDL_WSCONS_Init_Keyboard(const char *dev)
}
input->keyboardID = SDL_GetNextObjectID();
SDL_AddKeyboard(input->keyboardID, NULL, false);
SDL_AddKeyboard(input->keyboardID, NULL);
input->keymap.map = SDL_calloc(KS_NUMKEYCODES, sizeof(struct wscons_keymap));
if (!input->keymap.map) {

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