Compare commits
252
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
badbf8da4e | ||
|
|
b140291cd0 | ||
|
|
70b12c1b1b | ||
|
|
2bbd74b4b6 | ||
|
|
add176e538 | ||
|
|
86384afbcf | ||
|
|
328f833d51 | ||
|
|
a002a6313e | ||
|
|
4fc5405f16 | ||
|
|
16d9f7316f | ||
|
|
95977f41b7 | ||
|
|
3302162ede | ||
|
|
29f857fed6 | ||
|
|
492ed877ea | ||
|
|
b1959ecf23 | ||
|
|
928454cbfe | ||
|
|
36b306a36c | ||
|
|
92570af7d3 | ||
|
|
5a9050aea3 | ||
|
|
3d9f4c3328 | ||
|
|
04ceb2d4a0 | ||
|
|
e6987e2452 | ||
|
|
4cd6df1997 | ||
|
|
9163913305 | ||
|
|
b3f4ba0725 | ||
|
|
354bda8dde | ||
|
|
8ccbfdf368 | ||
|
|
19b646849c | ||
|
|
48a83d69cc | ||
|
|
ec682cc794 | ||
|
|
d2d655b41f | ||
|
|
d6021b7d89 | ||
|
|
8dcb6db823 | ||
|
|
d0cfcf10bb | ||
|
|
dd791f6838 | ||
|
|
988714beb9 | ||
|
|
78756540cb | ||
|
|
205b5c9f44 | ||
|
|
bca30aafed | ||
|
|
840d5c16d2 | ||
|
|
25b9a686b0 | ||
|
|
54c2f2c3f7 | ||
|
|
b9cf5f08db | ||
|
|
c7a36fa3c9 | ||
|
|
73ca5f53e7 | ||
|
|
2be2fb4918 | ||
|
|
fec1dd4a8b | ||
|
|
2a3a8f736c | ||
|
|
d3aff13aa3 | ||
|
|
54fb312a2c | ||
|
|
20aa0ad1c5 | ||
|
|
ff667d35f2 | ||
|
|
ff9599fb7e | ||
|
|
0448f20394 | ||
|
|
db07924104 | ||
|
|
e60acdc477 | ||
|
|
d69f658835 | ||
|
|
3eb9328d3e | ||
|
|
a8589a8422 | ||
|
|
0bdaaf6c76 | ||
|
|
390197d3aa | ||
|
|
9fafba49dc | ||
|
|
5d47efe7fb | ||
|
|
824234accc | ||
|
|
6519158ae5 | ||
|
|
00718d60d2 | ||
|
|
18c2e179ee | ||
|
|
21ae008fc2 | ||
|
|
97a8bb44e6 | ||
|
|
5d33fce898 | ||
|
|
bb5df96f69 | ||
|
|
12b97944f3 | ||
|
|
0f17fbe1ca | ||
|
|
c3480ca99c | ||
|
|
936d94c2ee | ||
|
|
6cb55ebd46 | ||
|
|
482c5130eb | ||
|
|
066bcc5204 | ||
|
|
21baa27bea | ||
|
|
93fd4a1c80 | ||
|
|
7135779599 | ||
|
|
62c151d044 | ||
|
|
11d38fc23b | ||
|
|
d027f0ae6e | ||
|
|
44290c204e | ||
|
|
0b69860af6 | ||
|
|
e7a1ae0ea5 | ||
|
|
7af36d6c40 | ||
|
|
d1ae1163dd | ||
|
|
b2cf5729b4 | ||
|
|
11b8dd76db | ||
|
|
56507a6122 | ||
|
|
8d4324cba2 | ||
|
|
35408a2126 | ||
|
|
e5b9dfd181 | ||
|
|
e8a5d07e5e | ||
|
|
8c1daf0caf | ||
|
|
ad2b211f75 | ||
|
|
414ae344af | ||
|
|
71af2c020c | ||
|
|
e755f50072 | ||
|
|
a0b8275e9c | ||
|
|
ea362839b1 | ||
|
|
e7dd5d841b | ||
|
|
5594d03da0 | ||
|
|
f2ae66b64f | ||
|
|
393d99338f | ||
|
|
4d88280931 | ||
|
|
e8cc359b5e | ||
|
|
3b4a198655 | ||
|
|
03dd1520a3 | ||
|
|
a6fd74fa3b | ||
|
|
03b36bac94 | ||
|
|
a96677bdf6 | ||
|
|
67f89d0a2b | ||
|
|
f6de8877ec | ||
|
|
7c189b1f17 | ||
|
|
a7947080c0 | ||
|
|
08c82a3781 | ||
|
|
589aea50c2 | ||
|
|
72acd7c9df | ||
|
|
1a70d1158e | ||
|
|
ae915c6516 | ||
|
|
54d573332e | ||
|
|
0204a69f6b | ||
|
|
b2689ff76a | ||
|
|
611940fb80 | ||
|
|
16c0329a2a | ||
|
|
2743716132 | ||
|
|
a744eee993 | ||
|
|
0e24267eb5 | ||
|
|
f4d6043aa4 | ||
|
|
9fb9bd31a3 | ||
|
|
c3828bb0a3 | ||
|
|
40371f0907 | ||
|
|
94f9434564 | ||
|
|
bfaf247d30 | ||
|
|
2287c43b59 | ||
|
|
15cc0f5f91 | ||
|
|
68e0108b1c | ||
|
|
7b3796bc39 | ||
|
|
b5bc6d2cc4 | ||
|
|
0d1d4ea1f9 | ||
|
|
1a48f897f2 | ||
|
|
2b42789de6 | ||
|
|
b9c1da10ba | ||
|
|
56f5a76696 | ||
|
|
c7e8977e60 | ||
|
|
e6ba3612db | ||
|
|
5e77fb314c | ||
|
|
1a2841deb1 | ||
|
|
688637eca8 | ||
|
|
85d1d70ca1 | ||
|
|
09356c709a | ||
|
|
07b9e86d02 | ||
|
|
8e46e5d8b4 | ||
|
|
96292a5b46 | ||
|
|
ffa618c00b | ||
|
|
291b9b3c82 | ||
|
|
ec45117f0f | ||
|
|
0d7aff9c56 | ||
|
|
d31b239288 | ||
|
|
b1cadf0e99 | ||
|
|
c1f67585e6 | ||
|
|
93988e28c0 | ||
|
|
edef6e66e9 | ||
|
|
e3f47809c4 | ||
|
|
f759e7ac59 | ||
|
|
544eb2c5a9 | ||
|
|
30e3eba20a | ||
|
|
f0e85a2a9c | ||
|
|
106af5b46a | ||
|
|
522716ed90 | ||
|
|
a65fbb0211 | ||
|
|
46ec859bd1 | ||
|
|
2a7aa4eae4 | ||
|
|
c31ddf021e | ||
|
|
eaa2a8239f | ||
|
|
d313ecb737 | ||
|
|
64b2af0340 | ||
|
|
58d0702948 | ||
|
|
707717e94b | ||
|
|
a140bba55a | ||
|
|
f4ddacacd0 | ||
|
|
ebba656bdb | ||
|
|
b78c61d67a | ||
|
|
4210aa61e1 | ||
|
|
d8a345d924 | ||
|
|
b8dc9767da | ||
|
|
1ab01b9367 | ||
|
|
ee371ff740 | ||
|
|
ef58dd77ca | ||
|
|
e6a7121904 | ||
|
|
a6ed8ab59d | ||
|
|
bd40d0ded1 | ||
|
|
68bfcb6c54 | ||
|
|
0d01efca52 | ||
|
|
0e65e04ce1 | ||
|
|
58d351fe98 | ||
|
|
9b71f18141 | ||
|
|
554f08bac3 | ||
|
|
913813a933 | ||
|
|
4e34c771e4 | ||
|
|
9995174e68 | ||
|
|
5a0197d430 | ||
|
|
4a55143e15 | ||
|
|
87c9bc1b1f | ||
|
|
16a57b70f7 | ||
|
|
69564cd0b1 | ||
|
|
da648b00e7 | ||
|
|
5886d90308 | ||
|
|
e84df0cad1 | ||
|
|
e482904111 | ||
|
|
b8ee44ca6a | ||
|
|
4a4abe4240 | ||
|
|
fe47f5cc30 | ||
|
|
5b64be0810 | ||
|
|
17656d051b | ||
|
|
233fce456a | ||
|
|
5290bb036c | ||
|
|
2bff72b4f6 | ||
|
|
08ebeaee5c | ||
|
|
12b56f5447 | ||
|
|
165b86e7b7 | ||
|
|
608101a185 | ||
|
|
554bee6aae | ||
|
|
3e0ce51067 | ||
|
|
7261c43342 | ||
|
|
ad57c6ea37 | ||
|
|
caecff650d | ||
|
|
f6300be4b2 | ||
|
|
bde5687a3c | ||
|
|
0f3504f78d | ||
|
|
0aaa0321cc | ||
|
|
caaaf52583 | ||
|
|
56449f167d | ||
|
|
c7325228dc | ||
|
|
079967afa5 | ||
|
|
2ed55b614c | ||
|
|
28721e3cd2 | ||
|
|
9d9845d063 | ||
|
|
a96dc76831 | ||
|
|
ad8e517227 | ||
|
|
8d578d590f | ||
|
|
6b4a211374 | ||
|
|
55b023c961 | ||
|
|
e2d0fe3e2f | ||
|
|
6b56ff7a97 | ||
|
|
67f796ebde | ||
|
|
06da7490fc | ||
|
|
af83c442d3 | ||
|
|
d726e98596 |
No files matched your search
@@ -20,7 +20,6 @@ class AppleArch(Enum):
|
||||
class MsvcArch(Enum):
|
||||
X86 = "x86"
|
||||
X64 = "x64"
|
||||
Arm32 = "arm"
|
||||
Arm64 = "arm64"
|
||||
|
||||
|
||||
@@ -54,6 +53,7 @@ class SdlPlatform(Enum):
|
||||
Riscos = "riscos"
|
||||
FreeBSD = "freebsd"
|
||||
NetBSD = "netbsd"
|
||||
OpenBSD = "openbsd"
|
||||
|
||||
|
||||
class Msys2Platform(Enum):
|
||||
@@ -108,7 +108,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", ),
|
||||
@@ -137,6 +136,7 @@ JOB_SPECS = {
|
||||
"vita-pvr": JobSpec(name="Sony PlayStation Vita (GLES w/ PVR_PSP2)", os=JobOs.UbuntuLatest, platform=SdlPlatform.Vita, artifact="SDL-vita-pvr", container="vitasdk/vitasdk:latest", vita_gles=VitaGLES.Pvr, ),
|
||||
"riscos": JobSpec(name="RISC OS", os=JobOs.UbuntuLatest, platform=SdlPlatform.Riscos, artifact="SDL-riscos", container="riscosdotinfo/riscos-gccsdk-4.7:latest", ),
|
||||
"netbsd": JobSpec(name="NetBSD", os=JobOs.UbuntuLatest, platform=SdlPlatform.NetBSD, artifact="SDL-netbsd-x64", ),
|
||||
"openbsd": JobSpec(name="OpenBSD", os=JobOs.UbuntuLatest, platform=SdlPlatform.OpenBSD, artifact="SDL-openbsd-x64", ),
|
||||
"freebsd": JobSpec(name="FreeBSD", os=JobOs.UbuntuLatest, platform=SdlPlatform.FreeBSD, artifact="SDL-freebsd-x64", ),
|
||||
}
|
||||
|
||||
@@ -174,6 +174,7 @@ class JobDetails:
|
||||
brew_packages: list[str] = dataclasses.field(default_factory=list)
|
||||
cmake_toolchain_file: str = ""
|
||||
cmake_arguments: list[str] = dataclasses.field(default_factory=list)
|
||||
cmake_generator: str = "Ninja"
|
||||
cmake_build_arguments: list[str] = dataclasses.field(default_factory=list)
|
||||
clang_tidy: bool = True
|
||||
cppflags: list[str] = dataclasses.field(default_factory=list)
|
||||
@@ -222,6 +223,7 @@ class JobDetails:
|
||||
check_sources: bool = False
|
||||
setup_python: bool = False
|
||||
pypi_packages: list[str] = dataclasses.field(default_factory=list)
|
||||
binutils_strings: str = "strings"
|
||||
|
||||
def to_workflow(self, enable_artifacts: bool) -> dict[str, str|bool]:
|
||||
data = {
|
||||
@@ -255,6 +257,7 @@ class JobDetails:
|
||||
"cflags": my_shlex_join(self.cppflags + self.cflags),
|
||||
"cxxflags": my_shlex_join(self.cppflags + self.cxxflags),
|
||||
"ldflags": my_shlex_join(self.ldflags),
|
||||
"cmake-generator": self.cmake_generator,
|
||||
"cmake-toolchain-file": self.cmake_toolchain_file,
|
||||
"clang-tidy": self.clang_tidy,
|
||||
"cmake-arguments": my_shlex_join(self.cmake_arguments),
|
||||
@@ -289,6 +292,7 @@ class JobDetails:
|
||||
"check-sources": self.check_sources,
|
||||
"setup-python": self.setup_python,
|
||||
"pypi-packages": my_shlex_join(self.pypi_packages),
|
||||
"binutils-strings": self.binutils_strings,
|
||||
}
|
||||
return {k: v for k, v in data.items() if v != ""}
|
||||
|
||||
@@ -403,10 +407,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
|
||||
@@ -512,11 +512,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:
|
||||
@@ -550,6 +553,10 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
|
||||
"testmultiaudio-apk",
|
||||
"testsprite-apk",
|
||||
]
|
||||
|
||||
# -fPIC is required after updating NDK from 21 to 28
|
||||
job.cflags.append("-fPIC")
|
||||
job.cxxflags.append("-fPIC")
|
||||
case SdlPlatform.Emscripten:
|
||||
job.clang_tidy = False # clang-tidy does not understand -gsource-map
|
||||
job.shared = False
|
||||
@@ -675,13 +682,16 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
|
||||
job.shared_lib = SharedLibType.SO_0
|
||||
job.static_lib = StaticLibType.A
|
||||
case SdlPlatform.N3ds:
|
||||
job.ccache = True
|
||||
job.cmake_generator = "Unix Makefiles"
|
||||
job.cmake_build_arguments.append("-j$(nproc)")
|
||||
job.ccache = False
|
||||
job.shared = False
|
||||
job.apt_packages = ["ccache", "ninja-build", "binutils"]
|
||||
job.apt_packages = []
|
||||
job.clang_tidy = False
|
||||
job.run_tests = False
|
||||
job.cc_from_cmake = True
|
||||
job.cmake_toolchain_file = "${DEVKITPRO}/cmake/3DS.cmake"
|
||||
job.binutils_strings = "/opt/devkitpro/devkitARM/bin/arm-none-eabi-strings"
|
||||
job.static_lib = StaticLibType.A
|
||||
case SdlPlatform.Msys2:
|
||||
job.ccache = True
|
||||
@@ -713,7 +723,7 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
|
||||
))
|
||||
job.cmake_toolchain_file = "/home/riscos/env/toolchain-riscos.cmake"
|
||||
job.static_lib = StaticLibType.A
|
||||
case SdlPlatform.FreeBSD | SdlPlatform.NetBSD:
|
||||
case SdlPlatform.FreeBSD | SdlPlatform.NetBSD | SdlPlatform.OpenBSD:
|
||||
job.cpactions = True
|
||||
job.no_cmake = True
|
||||
job.run_tests = False
|
||||
@@ -723,7 +733,7 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
|
||||
match spec.platform:
|
||||
case SdlPlatform.FreeBSD:
|
||||
job.cpactions_os = "freebsd"
|
||||
job.cpactions_version = "14.2"
|
||||
job.cpactions_version = "14.3"
|
||||
job.cpactions_arch = "x86-64"
|
||||
job.cpactions_setup_cmd = "sudo pkg update"
|
||||
job.cpactions_install_cmd = "sudo pkg install -y cmake ninja pkgconf libXcursor libXext libXinerama libXi libXfixes libXrandr libXScrnSaver libXxf86vm wayland wayland-protocols libxkbcommon mesa-libs libglvnd evdev-proto libinotify alsa-lib jackit pipewire pulseaudio sndio dbus zh-fcitx ibus libudev-devd"
|
||||
@@ -737,6 +747,12 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
|
||||
job.cpactions_arch = "x86-64"
|
||||
job.cpactions_setup_cmd = "export PATH=\"/usr/pkg/sbin:/usr/pkg/bin:/sbin:$PATH\"; export PKG_CONFIG_PATH=\"/usr/pkg/lib/pkgconfig\";export PKG_PATH=\"https://cdn.netBSD.org/pub/pkgsrc/packages/NetBSD/$(uname -p)/$(uname -r|cut -f \"1 2\" -d.)/All/\";echo \"PKG_PATH=$PKG_PATH\";echo \"uname -a -> \"$(uname -a)\"\";sudo -E sysctl -w security.pax.aslr.enabled=0;sudo -E sysctl -w security.pax.aslr.global=0;sudo -E pkgin clean;sudo -E pkgin update"
|
||||
job.cpactions_install_cmd = "sudo -E pkgin -y install cmake dbus pkgconf ninja-build pulseaudio libxkbcommon wayland wayland-protocols libinotify libusb1"
|
||||
case SdlPlatform.OpenBSD:
|
||||
job.cpactions_os = "openbsd"
|
||||
job.cpactions_version = "7.7"
|
||||
job.cpactions_arch = "x86-64"
|
||||
job.cpactions_setup_cmd = "sudo pkg_add -u"
|
||||
job.cpactions_install_cmd = "sudo pkg_add cmake ninja pkgconf wayland wayland-protocols libxkbcommon libinotify pulseaudio dbus ibus"
|
||||
case _:
|
||||
raise ValueError(f"Unsupported platform={spec.platform}")
|
||||
|
||||
|
||||
@@ -75,8 +75,8 @@ jobs:
|
||||
if: ${{ matrix.platform.android-ndk }}
|
||||
id: setup-ndk
|
||||
with:
|
||||
local-cache: true
|
||||
ndk-version: r21e
|
||||
local-cache: false
|
||||
ndk-version: r28c
|
||||
- name: 'Configure Android NDK variables'
|
||||
if: ${{ matrix.platform.android-ndk }}
|
||||
shell: sh
|
||||
@@ -201,7 +201,7 @@ jobs:
|
||||
#shell: ${{ matrix.platform.shell }}
|
||||
run: |
|
||||
${{ matrix.platform.source-cmd }}
|
||||
${{ matrix.platform.cmake-config-emulator }} cmake -S . -B build -GNinja \
|
||||
${{ matrix.platform.cmake-config-emulator }} cmake -S . -B build -G "${{ matrix.platform.cmake-generator }}" \
|
||||
-Wdeprecated -Wdev -Werror \
|
||||
${{ matrix.platform.cmake-toolchain-file != '' && format('-DCMAKE_TOOLCHAIN_FILE={0}', matrix.platform.cmake-toolchain-file) || '' }} \
|
||||
-DSDL_WERROR=${{ matrix.platform.werror }} \
|
||||
@@ -232,9 +232,9 @@ jobs:
|
||||
run: |
|
||||
echo "This should show us the SDL_REVISION"
|
||||
echo "Shared library:"
|
||||
${{ (matrix.platform.shared-lib && format('strings build/{0} | grep "Github Workflow"', matrix.platform.shared-lib)) || 'echo "<Shared library not supported by platform>"' }}
|
||||
${{ (matrix.platform.shared-lib && format('{0} build/{1} | grep "Github Workflow"', matrix.platform.binutils-strings, matrix.platform.shared-lib)) || 'echo "<Shared library not supported by platform>"' }}
|
||||
echo "Static library:"
|
||||
${{ (matrix.platform.static-lib && format('strings build/{0} | grep "Github Workflow"', matrix.platform.static-lib)) || 'echo "<Static library not supported by platform>"' }}
|
||||
${{ (matrix.platform.static-lib && format('{0} build/{1} | grep "Github Workflow"', matrix.platform.binutils-strings, matrix.platform.static-lib)) || 'echo "<Static library not supported by platform>"' }}
|
||||
- name: 'Run build-time tests (CMake)'
|
||||
id: tests
|
||||
if: ${{ !matrix.platform.no-cmake && matrix.platform.run-tests }}
|
||||
@@ -321,7 +321,7 @@ jobs:
|
||||
- name: 'Build (cross-platform-actions, BSD)'
|
||||
id: cpactions
|
||||
if: ${{ matrix.platform.cpactions }}
|
||||
uses: cross-platform-actions/action@v0.27.0
|
||||
uses: cross-platform-actions/action@v0.29.0
|
||||
with:
|
||||
operating_system: '${{ matrix.platform.cpactions-os }}'
|
||||
architecture: '${{ matrix.platform.cpactions-arch }}'
|
||||
@@ -406,6 +406,14 @@ jobs:
|
||||
build-scripts/test-versioning.sh
|
||||
python build-scripts/check_android_jni.py
|
||||
python build-scripts/check_stdlib_usage.py
|
||||
- name: 'Verify alignment of Android test apks'
|
||||
if: ${{ matrix.platform.android-ndk && !matrix.platform.no-cmake }}
|
||||
run: |
|
||||
find ./ -iname '*.apk' | xargs -L1 ./build-scripts/check_elf_alignment.sh
|
||||
- name: 'Verify alignment of Android .so files'
|
||||
if: ${{ matrix.platform.android-ndk && !matrix.platform.no-cmake }}
|
||||
run: |
|
||||
find ./ -iname '*.so' | xargs -L1 ./build-scripts/check_elf_alignment.sh
|
||||
- name: 'Upload binary package'
|
||||
uses: actions/upload-artifact@v4
|
||||
if: ${{ always() && matrix.platform.artifact != '' && (steps.package.outcome == 'success' || steps.cpactions.outcome == 'success') && (matrix.platform.enable-artifacts || steps.tests.outcome == 'failure') }}
|
||||
@@ -428,4 +436,4 @@ jobs:
|
||||
with:
|
||||
if-no-files-found: error
|
||||
name: '${{ matrix.platform.artifact }}-apks'
|
||||
path: build/test/*.apk
|
||||
path: build/test/*.apk
|
||||
@@ -256,7 +256,7 @@ jobs:
|
||||
|
||||
msvc:
|
||||
needs: [src]
|
||||
runs-on: windows-2019
|
||||
runs-on: windows-2025
|
||||
outputs:
|
||||
VC-x86: ${{ steps.releaser.outputs.VC-x86 }}
|
||||
VC-x64: ${{ steps.releaser.outputs.VC-x64 }}
|
||||
@@ -532,10 +532,11 @@ jobs:
|
||||
with:
|
||||
sparse-checkout: 'build-scripts/build-release.py'
|
||||
- name: 'Setup Android NDK'
|
||||
id: setup-ndk
|
||||
uses: nttld/setup-ndk@v1
|
||||
with:
|
||||
local-cache: true
|
||||
ndk-version: r21e
|
||||
local-cache: false
|
||||
ndk-version: r28c
|
||||
- name: 'Setup Java JDK'
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
@@ -561,6 +562,8 @@ jobs:
|
||||
run: |
|
||||
python build-scripts/build-release.py \
|
||||
--actions android \
|
||||
--android-api 21 \
|
||||
--android-ndk-home "${{ steps.setup-ndk.outputs.ndk-path }}" \
|
||||
--commit ${{ inputs.commit }} \
|
||||
--root "${{ steps.tar.outputs.path }}" \
|
||||
--github \
|
||||
@@ -607,8 +610,14 @@ jobs:
|
||||
python "${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}.aar" -o /tmp/SDL3-android
|
||||
echo "prefix=/tmp/SDL3-android" >>$GITHUB_OUTPUT
|
||||
echo "sdl3-aar=/tmp/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}.aar" >>$GITHUB_OUTPUT
|
||||
- name: 'Verify alignment of libSDL3.so (arm64-v8a/x86_64)'
|
||||
run: |
|
||||
set -e
|
||||
${{ steps.src.outputs.path }}/build-scripts/check_elf_alignment.sh ${{ steps.sdk.outputs.prefix }}/lib/arm64-v8a/libSDL3.so
|
||||
${{ steps.src.outputs.path }}/build-scripts/check_elf_alignment.sh ${{ steps.sdk.outputs.prefix }}/lib/x86_64/libSDL3.so
|
||||
- name: 'CMake (configure + build) x86, x64, arm32, arm64'
|
||||
run: |
|
||||
set -e
|
||||
android_abis="x86 x86_64 armeabi-v7a arm64-v8a"
|
||||
for android_abi in ${android_abis}; do
|
||||
echo "Configuring ${android_abi}..."
|
||||
|
||||
+81
-68
@@ -5,7 +5,7 @@ if(NOT DEFINED CMAKE_BUILD_TYPE)
|
||||
endif()
|
||||
|
||||
# See docs/release_checklist.md
|
||||
project(SDL3 LANGUAGES C VERSION "3.2.16")
|
||||
project(SDL3 LANGUAGES C VERSION "3.2.26")
|
||||
|
||||
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
|
||||
set(SDL3_MAINPROJECT ON)
|
||||
@@ -79,6 +79,12 @@ include("${SDL3_SOURCE_DIR}/cmake/PreseedEmscriptenCache.cmake")
|
||||
|
||||
SDL_DetectCompiler()
|
||||
SDL_DetectTargetCPUArchitectures(SDL_CPUS)
|
||||
if(APPLE AND CMAKE_OSX_ARCHITECTURES)
|
||||
list(LENGTH CMAKE_OSX_ARCHITECTURES _num_arches)
|
||||
if(_num_arches GREATER 1)
|
||||
set(APPLE_MULTIARCH TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Increment this if there is an incompatible change - but if that happens,
|
||||
# we should rename the library from SDL3 to SDL4, at which point this would
|
||||
@@ -183,26 +189,6 @@ if(MSVC)
|
||||
set(SDL_RELOCATABLE_DEFAULT ON)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
if(NOT SDL_LIBC)
|
||||
# Make sure /RTC1 is disabled, otherwise it will use functions from the CRT
|
||||
foreach(flag_var
|
||||
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
|
||||
string(REGEX REPLACE "/RTC(su|[1su])" "" ${flag_var} "${${flag_var}}")
|
||||
endforeach(flag_var)
|
||||
endif()
|
||||
|
||||
if(MSVC_CLANG)
|
||||
# clang-cl treats /W4 as '-Wall -Wextra' -- we don't need -Wextra
|
||||
foreach(flag_var
|
||||
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
|
||||
string(REGEX REPLACE "/W4" "/W3" ${flag_var} "${${flag_var}}")
|
||||
endforeach(flag_var)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(SDL_SHARED_DEFAULT ON)
|
||||
set(SDL_STATIC_DEFAULT ON)
|
||||
|
||||
@@ -370,7 +356,7 @@ dep_option(SDL_WASAPI "Use the Windows WASAPI audio driver" ON "WIN
|
||||
dep_option(SDL_RENDER_D3D "Enable the Direct3D 9 render driver" ON "SDL_RENDER;SDL_DIRECTX" OFF)
|
||||
dep_option(SDL_RENDER_D3D11 "Enable the Direct3D 11 render driver" ON "SDL_RENDER;SDL_DIRECTX" OFF)
|
||||
dep_option(SDL_RENDER_D3D12 "Enable the Direct3D 12 render driver" ON "SDL_RENDER;SDL_DIRECTX" OFF)
|
||||
dep_option(SDL_RENDER_METAL "Enable the Metal render driver" ON "SDL_RENDER;${APPLE}" OFF)
|
||||
dep_option(SDL_RENDER_METAL "Enable the Metal render driver" ON "SDL_RENDER;APPLE" OFF)
|
||||
dep_option(SDL_RENDER_GPU "Enable the SDL_GPU render driver" ON "SDL_RENDER;SDL_GPU" OFF)
|
||||
dep_option(SDL_VIVANTE "Use Vivante EGL video driver" ON "${UNIX_SYS};SDL_CPU_ARM32" OFF)
|
||||
dep_option(SDL_VULKAN "Enable Vulkan support" ON "SDL_VIDEO;ANDROID OR APPLE OR LINUX OR FREEBSD OR WINDOWS" OFF)
|
||||
@@ -421,6 +407,29 @@ if(SDL_PRESEED)
|
||||
SDL_Preseed_CMakeCache()
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
if(NOT SDL_LIBC)
|
||||
# Make sure /RTC1 is disabled, otherwise it will use functions from the CRT
|
||||
foreach(flag_var
|
||||
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
|
||||
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
||||
string(REGEX REPLACE "/RTC(su|[1su])" "" ${flag_var} "${${flag_var}}")
|
||||
endforeach(flag_var)
|
||||
set(CMAKE_MSVC_RUNTIME_CHECKS "")
|
||||
endif()
|
||||
|
||||
if(MSVC_CLANG)
|
||||
# clang-cl treats /W4 as '-Wall -Wextra' -- we don't need -Wextra
|
||||
foreach(flag_var
|
||||
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
|
||||
string(REGEX REPLACE "/W4" "/W3" ${flag_var} "${${flag_var}}")
|
||||
endforeach(flag_var)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(SDL_SHARED)
|
||||
add_library(SDL3-shared SHARED)
|
||||
add_library(SDL3::SDL3-shared ALIAS SDL3-shared)
|
||||
@@ -634,6 +643,11 @@ if(MSVC)
|
||||
# Mark SDL3.dll as compatible with Control-flow Enforcement Technology (CET)
|
||||
sdl_shared_link_options("-CETCOMPAT")
|
||||
endif()
|
||||
|
||||
# for VS >= 17.14 targeting ARM64: inline the Interlocked funcs
|
||||
if(MSVC_VERSION GREATER 1943 AND SDL_CPU_ARM64 AND NOT SDL_LIBC)
|
||||
sdl_compile_options(PRIVATE "/forceInterlockedFunctions-")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
|
||||
@@ -650,7 +664,7 @@ if(SDL_ASSEMBLY)
|
||||
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -mmmx")
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
check_x86_source_compiles([==[
|
||||
#include <mmintrin.h>
|
||||
void ints_add(int *dest, int *a, int *b, unsigned size) {
|
||||
for (; size >= 2; size -= 2, dest += 2, a += 2, b += 2) {
|
||||
@@ -660,7 +674,7 @@ if(SDL_ASSEMBLY)
|
||||
int main(int argc, char *argv[]) {
|
||||
ints_add((int*)0, (int*)0, (int*)0, 0);
|
||||
return 0;
|
||||
}" COMPILER_SUPPORTS_MMX)
|
||||
}]==] COMPILER_SUPPORTS_MMX)
|
||||
cmake_pop_check_state()
|
||||
if(COMPILER_SUPPORTS_MMX)
|
||||
set(HAVE_MMX TRUE)
|
||||
@@ -671,7 +685,7 @@ if(SDL_ASSEMBLY)
|
||||
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -msse")
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
check_x86_source_compiles([==[
|
||||
#include <xmmintrin.h>
|
||||
void floats_add(float *dest, float *a, float *b, unsigned size) {
|
||||
for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) {
|
||||
@@ -681,7 +695,7 @@ if(SDL_ASSEMBLY)
|
||||
int main(int argc, char **argv) {
|
||||
floats_add((float*)0, (float*)0, (float*)0, 0);
|
||||
return 0;
|
||||
}" COMPILER_SUPPORTS_SSE)
|
||||
}]==] COMPILER_SUPPORTS_SSE)
|
||||
cmake_pop_check_state()
|
||||
if(COMPILER_SUPPORTS_SSE)
|
||||
set(HAVE_SSE TRUE)
|
||||
@@ -692,7 +706,7 @@ if(SDL_ASSEMBLY)
|
||||
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -msse2")
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
check_x86_source_compiles([==[
|
||||
#include <emmintrin.h>
|
||||
void doubles_add(double *dest, double *a, double *b, unsigned size) {
|
||||
for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) {
|
||||
@@ -702,7 +716,7 @@ if(SDL_ASSEMBLY)
|
||||
int main(int argc, char **argv) {
|
||||
doubles_add((double*)0, (double*)0, (double*)0, 0);
|
||||
return 0;
|
||||
}" COMPILER_SUPPORTS_SSE2)
|
||||
}]==] COMPILER_SUPPORTS_SSE2)
|
||||
cmake_pop_check_state()
|
||||
if(COMPILER_SUPPORTS_SSE2)
|
||||
set(HAVE_SSE2 TRUE)
|
||||
@@ -713,7 +727,7 @@ if(SDL_ASSEMBLY)
|
||||
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -msse3")
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
check_x86_source_compiles([==[
|
||||
#include <pmmintrin.h>
|
||||
void ints_add(int *dest, int *a, int *b, unsigned size) {
|
||||
for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) {
|
||||
@@ -723,7 +737,7 @@ if(SDL_ASSEMBLY)
|
||||
int main(int argc, char **argv) {
|
||||
ints_add((int*)0, (int*)0, (int*)0, 0);
|
||||
return 0;
|
||||
}" COMPILER_SUPPORTS_SSE3)
|
||||
}]==] COMPILER_SUPPORTS_SSE3)
|
||||
cmake_pop_check_state()
|
||||
if(COMPILER_SUPPORTS_SSE3)
|
||||
set(HAVE_SSE3 TRUE)
|
||||
@@ -734,7 +748,7 @@ if(SDL_ASSEMBLY)
|
||||
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -msse4.1")
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
check_x86_source_compiles([==[
|
||||
#include <smmintrin.h>
|
||||
void ints_mul(int *dest, int *a, int *b, unsigned size) {
|
||||
for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) {
|
||||
@@ -744,7 +758,7 @@ if(SDL_ASSEMBLY)
|
||||
int main(int argc, char **argv) {
|
||||
ints_mul((int*)0, (int*)0, (int*)0, 0);
|
||||
return 0;
|
||||
}" COMPILER_SUPPORTS_SSE4_1)
|
||||
}]==] COMPILER_SUPPORTS_SSE4_1)
|
||||
cmake_pop_check_state()
|
||||
if(COMPILER_SUPPORTS_SSE4_1)
|
||||
set(HAVE_SSE4_1 TRUE)
|
||||
@@ -753,21 +767,16 @@ if(SDL_ASSEMBLY)
|
||||
if(SDL_SSE4_2)
|
||||
cmake_push_check_state()
|
||||
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -msse4.2 -mcrc32")
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -msse4.2")
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
check_x86_source_compiles([==[
|
||||
#include <nmmintrin.h>
|
||||
unsigned calc_crc32c(const char *text, unsigned len) {
|
||||
unsigned crc32c = ~0;
|
||||
for (; len >= 4; len -= 4, text += 4) {
|
||||
crc32c = (unsigned)_mm_crc32_u32(crc32c, *(unsigned*)text);
|
||||
}
|
||||
return crc32c;
|
||||
}
|
||||
__m128i bitmask;
|
||||
char data[16];
|
||||
int main(int argc, char **argv) {
|
||||
calc_crc32c(\"SDL_SSE4\",8);
|
||||
bitmask = _mm_cmpgt_epi64(_mm_set1_epi64x(0), _mm_loadu_si128((void*)data));
|
||||
return 0;
|
||||
}" COMPILER_SUPPORTS_SSE4_2)
|
||||
}]==] COMPILER_SUPPORTS_SSE4_2)
|
||||
cmake_pop_check_state()
|
||||
if(COMPILER_SUPPORTS_SSE4_2)
|
||||
set(HAVE_SSE4_2 TRUE)
|
||||
@@ -778,7 +787,7 @@ if(SDL_ASSEMBLY)
|
||||
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -mavx")
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
check_x86_source_compiles([==[
|
||||
#include <immintrin.h>
|
||||
void floats_add(float *dest, float *a, float *b, unsigned size) {
|
||||
for (; size >= 8; size -= 8, dest += 8, a += 8, b += 8) {
|
||||
@@ -788,7 +797,7 @@ if(SDL_ASSEMBLY)
|
||||
int main(int argc, char **argv) {
|
||||
floats_add((float*)0, (float*)0, (float*)0, 0);
|
||||
return 0;
|
||||
}" COMPILER_SUPPORTS_AVX)
|
||||
}]==] COMPILER_SUPPORTS_AVX)
|
||||
cmake_pop_check_state()
|
||||
if(COMPILER_SUPPORTS_AVX)
|
||||
set(HAVE_AVX TRUE)
|
||||
@@ -799,7 +808,7 @@ if(SDL_ASSEMBLY)
|
||||
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -mavx2")
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
check_x86_source_compiles([==[
|
||||
#include <immintrin.h>
|
||||
void ints_add(int *dest, int *a, int *b, unsigned size) {
|
||||
for (; size >= 8; size -= 8, dest += 8, a += 8, b += 8) {
|
||||
@@ -809,7 +818,7 @@ if(SDL_ASSEMBLY)
|
||||
int main(int argc, char **argv) {
|
||||
ints_add((int*)0, (int*)0, (int*)0, 0);
|
||||
return 0;
|
||||
}" COMPILER_SUPPORTS_AVX2)
|
||||
}]==] COMPILER_SUPPORTS_AVX2)
|
||||
cmake_pop_check_state()
|
||||
if(COMPILER_SUPPORTS_AVX2)
|
||||
set(HAVE_AVX2 TRUE)
|
||||
@@ -820,7 +829,7 @@ if(SDL_ASSEMBLY)
|
||||
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -mavx512f")
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
check_x86_source_compiles([==[
|
||||
#include <immintrin.h>
|
||||
void floats_add(float *dest, float *a, float *b, unsigned size) {
|
||||
for (; size >= 16; size -= 16, dest += 16, a += 16, b += 16) {
|
||||
@@ -830,7 +839,7 @@ if(SDL_ASSEMBLY)
|
||||
int main(int argc, char **argv) {
|
||||
floats_add((float*)0, (float*)0, (float*)0, 0);
|
||||
return 0;
|
||||
}" COMPILER_SUPPORTS_AVX512F)
|
||||
}]==] COMPILER_SUPPORTS_AVX512F)
|
||||
cmake_pop_check_state()
|
||||
if(COMPILER_SUPPORTS_AVX512F)
|
||||
set(HAVE_AVX512F TRUE)
|
||||
@@ -838,18 +847,17 @@ if(SDL_ASSEMBLY)
|
||||
endif()
|
||||
|
||||
if(SDL_ARMNEON)
|
||||
check_c_source_compiles("
|
||||
#include <arm_neon.h>
|
||||
void floats_add(float *dest, float *a, float *b, unsigned size) {
|
||||
for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) {
|
||||
vst1q_f32(dest, vaddq_f32(vld1q_f32(a), vld1q_f32(b)));
|
||||
}
|
||||
check_arm_source_compiles([==[
|
||||
#include <arm_neon.h>
|
||||
void floats_add(float *dest, float *a, float *b, unsigned size) {
|
||||
for (; size >= 4; size -= 4, dest += 4, a += 4, b += 4) {
|
||||
vst1q_f32(dest, vaddq_f32(vld1q_f32(a), vld1q_f32(b)));
|
||||
}
|
||||
int main(int argc, char *argv[]) {
|
||||
floats_add((float*)0, (float*)0, (float*)0, 0);
|
||||
return 0;
|
||||
}" COMPILER_SUPPORTS_ARMNEON)
|
||||
|
||||
}
|
||||
int main(int argc, char *argv[]) {
|
||||
floats_add((float*)0, (float*)0, (float*)0, 0);
|
||||
return 0;
|
||||
}]==] COMPILER_SUPPORTS_ARMNEON)
|
||||
if(COMPILER_SUPPORTS_ARMNEON)
|
||||
set(HAVE_ARMNEON TRUE)
|
||||
endif()
|
||||
@@ -1052,8 +1060,10 @@ if(SDL_LIBC)
|
||||
cmake_push_check_state()
|
||||
if(MSVC)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -we4244 -WX") # 'conversion' conversion from 'type1' to 'type2', possible loss of data
|
||||
else()
|
||||
elseif(HAVE_GCC_WFLOAT_CONVERSION)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -Wfloat-conversion -Werror")
|
||||
else()
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS " -Wconversion -Werror")
|
||||
endif()
|
||||
foreach(math_fn isinf isnan)
|
||||
string(TOUPPER "${math_fn}" MATH_FN)
|
||||
@@ -1091,6 +1101,7 @@ if(SDL_LIBC)
|
||||
check_symbol_exists(gethostname "unistd.h" HAVE_GETHOSTNAME)
|
||||
check_symbol_exists(getpagesize "unistd.h" HAVE_GETPAGESIZE)
|
||||
check_symbol_exists(sigaction "signal.h" HAVE_SIGACTION)
|
||||
check_symbol_exists(sigtimedwait "signal.h" HAVE_SIGTIMEDWAIT)
|
||||
check_symbol_exists(setjmp "setjmp.h" HAVE_SETJMP)
|
||||
check_symbol_exists(nanosleep "time.h" HAVE_NANOSLEEP)
|
||||
check_symbol_exists(gmtime_r "time.h" HAVE_GMTIME_R)
|
||||
@@ -1336,9 +1347,7 @@ if(ANDROID)
|
||||
set(HAVE_SDL_HAPTIC TRUE)
|
||||
endif()
|
||||
|
||||
if(SDL_HIDAPI)
|
||||
CheckHIDAPI()
|
||||
endif()
|
||||
CheckHIDAPI()
|
||||
|
||||
if(SDL_JOYSTICK)
|
||||
set(SDL_JOYSTICK_ANDROID 1)
|
||||
@@ -1480,6 +1489,9 @@ if(ANDROID)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(TARGET SDL3-static)
|
||||
target_link_options(SDL3-static INTERFACE "-Wl,-u,JNI_OnLoad")
|
||||
endif()
|
||||
|
||||
elseif(EMSCRIPTEN)
|
||||
# Hide noisy warnings that intend to aid mostly during initial stages of porting a new
|
||||
@@ -1905,7 +1917,7 @@ elseif(WINDOWS)
|
||||
target_compile_options(SDL_uclibc PRIVATE $<$<COMPILE_LANGUAGE:C,CXX>:/GS-> $<$<COMPILE_LANGUAGE:C,CXX>:/Gs1048576>)
|
||||
if(SDL_CPU_X86)
|
||||
target_compile_options(SDL3-shared PRIVATE "/arch:SSE")
|
||||
target_compile_options(SDL3-SDL_uclibc PRIVATE "/arch:SSE")
|
||||
target_compile_options(SDL_uclibc PRIVATE "/arch:SSE")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -2954,7 +2966,7 @@ if(WINDOWS)
|
||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/process/windows/*.c")
|
||||
set(SDL_PROCESS_WINDOWS 1)
|
||||
set(HAVE_SDL_PROCESS TRUE)
|
||||
else()
|
||||
elseif(NOT ANDROID)
|
||||
check_c_source_compiles("
|
||||
#include <spawn.h>
|
||||
#include <unistd.h>
|
||||
@@ -3144,14 +3156,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")
|
||||
|
||||
@@ -781,7 +781,6 @@
|
||||
<ClCompile Include="..\..\src\render\opengl\SDL_shaders_gl.c" />
|
||||
<ClCompile Include="..\..\src\render\opengles2\SDL_render_gles2.c" />
|
||||
<ClCompile Include="..\..\src\render\opengles2\SDL_shaders_gles2.c" />
|
||||
<ClCompile Include="..\..\src\render\SDL_d3dmath.c" />
|
||||
<ClCompile Include="..\..\src\render\SDL_render.c" />
|
||||
<ClCompile Include="..\..\src\render\SDL_render_unsupported.c" />
|
||||
<ClCompile Include="..\..\src\render\SDL_yuv_sw.c" />
|
||||
|
||||
@@ -108,7 +108,6 @@
|
||||
<ClCompile Include="..\..\src\render\opengl\SDL_shaders_gl.c" />
|
||||
<ClCompile Include="..\..\src\render\opengles2\SDL_render_gles2.c" />
|
||||
<ClCompile Include="..\..\src\render\opengles2\SDL_shaders_gles2.c" />
|
||||
<ClCompile Include="..\..\src\render\SDL_d3dmath.c" />
|
||||
<ClCompile Include="..\..\src\render\SDL_render.c" />
|
||||
<ClCompile Include="..\..\src\render\SDL_render_unsupported.c" />
|
||||
<ClCompile Include="..\..\src\render\SDL_yuv_sw.c" />
|
||||
|
||||
@@ -627,7 +627,6 @@
|
||||
<ClCompile Include="..\..\src\render\opengl\SDL_shaders_gl.c" />
|
||||
<ClCompile Include="..\..\src\render\opengles2\SDL_render_gles2.c" />
|
||||
<ClCompile Include="..\..\src\render\opengles2\SDL_shaders_gles2.c" />
|
||||
<ClCompile Include="..\..\src\render\SDL_d3dmath.c" />
|
||||
<ClCompile Include="..\..\src\render\SDL_render.c" />
|
||||
<ClCompile Include="..\..\src\render\SDL_render_unsupported.c" />
|
||||
<ClCompile Include="..\..\src\render\SDL_yuv_sw.c" />
|
||||
|
||||
@@ -1460,7 +1460,6 @@
|
||||
<ClCompile Include="..\..\src\sensor\windows\SDL_windowssensor.c">
|
||||
<Filter>sensor\windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\render\SDL_d3dmath.c">
|
||||
<Filter>render</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\render\SDL_render.c">
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>3.2.16</string>
|
||||
<string>3.2.26</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>SDLX</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>3.2.16</string>
|
||||
<string>3.2.26</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -292,7 +292,6 @@
|
||||
A7D8BA2523E2514400DCD162 /* SDL_drawpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FC23E2514000DCD162 /* SDL_drawpoint.c */; };
|
||||
A7D8BA2B23E2514400DCD162 /* SDL_blendfillrect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FD23E2514000DCD162 /* SDL_blendfillrect.c */; };
|
||||
A7D8BA3123E2514400DCD162 /* SDL_rotate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FE23E2514000DCD162 /* SDL_rotate.h */; };
|
||||
A7D8BA3723E2514400DCD162 /* SDL_d3dmath.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FF23E2514000DCD162 /* SDL_d3dmath.c */; };
|
||||
A7D8BA4923E2514400DCD162 /* SDL_render_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90423E2514000DCD162 /* SDL_render_gles2.c */; };
|
||||
A7D8BA4F23E2514400DCD162 /* SDL_shaders_gles2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90523E2514000DCD162 /* SDL_shaders_gles2.h */; };
|
||||
A7D8BA5523E2514400DCD162 /* SDL_gles2funcs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90623E2514000DCD162 /* SDL_gles2funcs.h */; };
|
||||
@@ -869,7 +868,6 @@
|
||||
A7D8A8FC23E2514000DCD162 /* SDL_drawpoint.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_drawpoint.c; sourceTree = "<group>"; };
|
||||
A7D8A8FD23E2514000DCD162 /* SDL_blendfillrect.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_blendfillrect.c; sourceTree = "<group>"; };
|
||||
A7D8A8FE23E2514000DCD162 /* SDL_rotate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_rotate.h; sourceTree = "<group>"; };
|
||||
A7D8A8FF23E2514000DCD162 /* SDL_d3dmath.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_d3dmath.c; sourceTree = "<group>"; };
|
||||
A7D8A90423E2514000DCD162 /* SDL_render_gles2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_render_gles2.c; sourceTree = "<group>"; };
|
||||
A7D8A90523E2514000DCD162 /* SDL_shaders_gles2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_shaders_gles2.h; sourceTree = "<group>"; };
|
||||
A7D8A90623E2514000DCD162 /* SDL_gles2funcs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_gles2funcs.h; sourceTree = "<group>"; };
|
||||
@@ -2135,7 +2133,6 @@
|
||||
A7D8A90C23E2514000DCD162 /* opengl */,
|
||||
A7D8A90323E2514000DCD162 /* opengles2 */,
|
||||
A7D8A8EF23E2514000DCD162 /* software */,
|
||||
A7D8A8FF23E2514000DCD162 /* SDL_d3dmath.c */,
|
||||
A7D8A8DC23E2514000DCD162 /* SDL_d3dmath.h */,
|
||||
A7D8A8DB23E2514000DCD162 /* SDL_render.c */,
|
||||
E4F7981D2AD8D86A00669F54 /* SDL_render_unsupported.c */,
|
||||
@@ -2833,7 +2830,7 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "# Build an xcframework with both device and simulator files for all platforms.\n# Adapted from an answer in\n# https://developer.apple.com/forums/thread/666335?answerId=685927022#685927022\n\nif [ \"$XCODE_VERSION_ACTUAL\" -lt 1100 ]\nthen\n echo \"error: Building an xcframework requires Xcode 11 minimum.\"\n exit 1\nfi\n\nFRAMEWORK_NAME=\"SDL3\"\nPROJECT_NAME=\"SDL\"\nSCHEME=\"SDL3\"\n\nMACOS_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-macosx.xcarchive\"\nIOS_SIMULATOR_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphonesimulator.xcarchive\"\nIOS_DEVICE_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphoneos.xcarchive\"\nTVOS_SIMULATOR_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-appletvsimulator.xcarchive\"\nTVOS_DEVICE_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-appletvos.xcarchive\"\n\nOUTPUT_DIR=\"./build/\"\n\n# macOS\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${MACOS_ARCHIVE_PATH} \\\n -destination 'generic/platform=macOS,name=Any Mac' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n \n# iOS simulator\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${IOS_SIMULATOR_ARCHIVE_PATH} \\\n -destination 'generic/platform=iOS Simulator' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# iOS device\nxcodebuild archive \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${IOS_DEVICE_ARCHIVE_PATH} \\\n -destination 'generic/platform=iOS' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# tvOS simulator\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${TVOS_SIMULATOR_ARCHIVE_PATH} \\\n -destination 'generic/platform=tvOS Simulator' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# tvOS device\nxcodebuild archive \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${TVOS_DEVICE_ARCHIVE_PATH} \\\n -destination 'generic/platform=tvOS' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# Clean-up any existing instance of this xcframework from the Products directory\nrm -rf \"${OUTPUT_DIR}${FRAMEWORK_NAME}.xcframework\"\n\n# Create final xcframework\nxcodebuild -create-xcframework \\\n -framework \"${MACOS_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${IOS_DEVICE_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${IOS_SIMULATOR_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${TVOS_DEVICE_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${TVOS_SIMULATOR_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -output ${OUTPUT_DIR}/${FRAMEWORK_NAME}.xcframework\n\n# Ensure git doesn't pick up on our Products folder. \nrm -rf ${OUTPUT_DIR}/.gitignore\necho \"*\" >> ${OUTPUT_DIR}/.gitignore\n";
|
||||
shellScript = "# Build an xcframework with both device and simulator files for all platforms.\n# Adapted from an answer in\n# https://developer.apple.com/forums/thread/666335?answerId=685927022#685927022\n\nif [ \"$XCODE_VERSION_ACTUAL\" -lt 1100 ]\nthen\n echo \"error: Building an xcframework requires Xcode 11 minimum.\"\n exit 1\nfi\n\nFRAMEWORK_NAME=\"SDL3\"\nPROJECT_NAME=\"SDL\"\nSCHEME=\"SDL3\"\n\nMACOS_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-macosx.xcarchive\"\nIOS_SIMULATOR_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphonesimulator.xcarchive\"\nIOS_DEVICE_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphoneos.xcarchive\"\nTVOS_SIMULATOR_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-appletvsimulator.xcarchive\"\nTVOS_DEVICE_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-appletvos.xcarchive\"\n\nOUTPUT_DIR=\"./build/\"\n\n# macOS\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${MACOS_ARCHIVE_PATH} \\\n -destination 'generic/platform=macOS,name=Any Mac' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n \n# iOS simulator\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${IOS_SIMULATOR_ARCHIVE_PATH} \\\n -destination 'generic/platform=iOS Simulator' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# iOS device\nxcodebuild archive \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${IOS_DEVICE_ARCHIVE_PATH} \\\n -destination 'generic/platform=iOS' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# tvOS simulator\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${TVOS_SIMULATOR_ARCHIVE_PATH} \\\n -destination 'generic/platform=tvOS Simulator' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# tvOS device\nxcodebuild archive \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${TVOS_DEVICE_ARCHIVE_PATH} \\\n -destination 'generic/platform=tvOS' \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# Clean-up any existing instance of this xcframework from the Products directory\nrm -rf \"${OUTPUT_DIR}${FRAMEWORK_NAME}.xcframework\"\n\n# Create final xcframework\nxcodebuild -create-xcframework \\\n -framework \"${MACOS_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -debug-symbols \"${MACOS_ARCHIVE_PATH}\"/dSYMs/$FRAMEWORK_NAME.framework.dSYM \\\n -framework \"${IOS_DEVICE_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -debug-symbols \"${IOS_DEVICE_ARCHIVE_PATH}\"/dSYMs/$FRAMEWORK_NAME.framework.dSYM \\\n -framework \"${IOS_SIMULATOR_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -debug-symbols \"${IOS_SIMULATOR_ARCHIVE_PATH}\"/dSYMs/$FRAMEWORK_NAME.framework.dSYM \\\n -framework \"${TVOS_DEVICE_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -debug-symbols \"${TVOS_DEVICE_ARCHIVE_PATH}\"/dSYMs/$FRAMEWORK_NAME.framework.dSYM \\\n -framework \"${TVOS_SIMULATOR_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -debug-symbols \"${TVOS_SIMULATOR_ARCHIVE_PATH}\"/dSYMs/$FRAMEWORK_NAME.framework.dSYM \\\n -output ${OUTPUT_DIR}/${FRAMEWORK_NAME}.xcframework\n\n# Ensure git doesn't pick up on our Products folder. \nrm -rf ${OUTPUT_DIR}/.gitignore\necho \"*\" >> ${OUTPUT_DIR}/.gitignore\n";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
@@ -2903,7 +2900,6 @@
|
||||
A7D8BBE723E2574800DCD162 /* SDL_uikitviewcontroller.m in Sources */,
|
||||
A7D8ADF223E2514100DCD162 /* SDL_blit_A.c in Sources */,
|
||||
A7D8BBDD23E2574800DCD162 /* SDL_uikitmodes.m in Sources */,
|
||||
A7D8BA3723E2514400DCD162 /* SDL_d3dmath.c in Sources */,
|
||||
F3A9AE9C2C8A13C100AAC390 /* SDL_pipeline_gpu.c in Sources */,
|
||||
75E0915A241EA924004729E1 /* SDL_virtualjoystick.c in Sources */,
|
||||
F338A11A2D1B37E4007CDFDF /* SDL_tray.c in Sources */,
|
||||
@@ -3086,7 +3082,7 @@
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
DEPLOYMENT_POSTPROCESSING = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 201.0.0;
|
||||
DYLIB_CURRENT_VERSION = 201.16.0;
|
||||
DYLIB_CURRENT_VERSION = 201.26.0;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_ALTIVEC_EXTENSIONS = YES;
|
||||
@@ -3121,7 +3117,7 @@
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MARKETING_VERSION = 3.2.16;
|
||||
MARKETING_VERSION = 3.2.26;
|
||||
OTHER_LDFLAGS = "$(CONFIG_FRAMEWORK_LDFLAGS)";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL3;
|
||||
PRODUCT_NAME = SDL3;
|
||||
@@ -3138,6 +3134,8 @@
|
||||
baseConfigurationReference = F3F7BE3B2CBD79D200C984AF /* config.xcconfig */;
|
||||
buildSettings = {
|
||||
CLANG_LINK_OBJC_RUNTIME = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
OTHER_LDFLAGS = "-liconv";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
};
|
||||
@@ -3150,7 +3148,7 @@
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 201.0.0;
|
||||
DYLIB_CURRENT_VERSION = 201.16.0;
|
||||
DYLIB_CURRENT_VERSION = 201.26.0;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
@@ -3182,7 +3180,7 @@
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MARKETING_VERSION = 3.2.16;
|
||||
MARKETING_VERSION = 3.2.26;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_LDFLAGS = "$(CONFIG_FRAMEWORK_LDFLAGS)";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL3;
|
||||
@@ -3200,6 +3198,8 @@
|
||||
baseConfigurationReference = F3F7BE3B2CBD79D200C984AF /* config.xcconfig */;
|
||||
buildSettings = {
|
||||
CLANG_LINK_OBJC_RUNTIME = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
OTHER_LDFLAGS = "-liconv";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Title SDL 3.2.16
|
||||
Title SDL 3.2.26
|
||||
Version 1
|
||||
Description SDL Library for macOS (http://www.libsdl.org)
|
||||
DefaultLocation /Library/Frameworks
|
||||
|
||||
@@ -7,4 +7,4 @@
|
||||
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
|
||||
|
||||
# Min runtime API level
|
||||
APP_PLATFORM=android-16
|
||||
APP_PLATFORM=android-21
|
||||
@@ -61,7 +61,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
private static final String TAG = "SDL";
|
||||
private static final int SDL_MAJOR_VERSION = 3;
|
||||
private static final int SDL_MINOR_VERSION = 2;
|
||||
private static final int SDL_MICRO_VERSION = 16;
|
||||
private static final int SDL_MICRO_VERSION = 26;
|
||||
/*
|
||||
// Display InputType.SOURCE/CLASS of events and devices
|
||||
//
|
||||
@@ -1128,6 +1128,11 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
|
||||
int orientation_landscape = -1;
|
||||
int orientation_portrait = -1;
|
||||
|
||||
if (w <= 1 || h <= 1) {
|
||||
// Invalid width/height, ignore this request
|
||||
return;
|
||||
}
|
||||
|
||||
/* If set, hint "explicitly controls which UI orientations are allowed". */
|
||||
if (hint.contains("LandscapeRight") && hint.contains("LandscapeLeft")) {
|
||||
orientation_landscape = ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE;
|
||||
@@ -2196,7 +2201,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() {
|
||||
@@ -2214,10 +2223,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
|
||||
|
||||
@@ -15,6 +15,7 @@ import android.view.Display;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.PointerIcon;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
@@ -362,6 +363,16 @@ public class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent android internal NullPointerException (https://github.com/libsdl-org/SDL/issues/13306)
|
||||
@Override
|
||||
public PointerIcon onResolvePointerIcon(MotionEvent event, int pointerIndex) {
|
||||
try {
|
||||
return super.onResolvePointerIcon(event, pointerIndex);
|
||||
} catch (NullPointerException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Captured pointer events for API 26.
|
||||
public boolean onCapturedPointerEvent(MotionEvent event)
|
||||
{
|
||||
|
||||
@@ -542,6 +542,7 @@ class AndroidApiVersion:
|
||||
def __repr__(self) -> str:
|
||||
return f"<{self.name} ({'.'.join(str(v) for v in self.ints)})>"
|
||||
|
||||
ANDROID_ABI_EXTRA_LINK_OPTIONS = {}
|
||||
|
||||
class Releaser:
|
||||
def __init__(self, release_info: dict, commit: str, revision: str, root: Path, dist_path: Path, section_printer: SectionPrinter, executer: Executer, cmake_generator: str, deps_path: Path, overwrite: bool, github: bool, fast: bool):
|
||||
@@ -1013,6 +1014,7 @@ class Releaser:
|
||||
android_devel_file_tree = ArchiveFileTree()
|
||||
|
||||
for android_abi in android_abis:
|
||||
extra_link_options = ANDROID_ABI_EXTRA_LINK_OPTIONS.get(android_abi, "")
|
||||
with self.section_printer.group(f"Building for Android {android_api} {android_abi}"):
|
||||
build_dir = self.root / "build-android" / f"{android_abi}-build"
|
||||
install_dir = self.root / "install-android" / f"{android_abi}-install"
|
||||
@@ -1023,8 +1025,11 @@ class Releaser:
|
||||
"cmake",
|
||||
"-S", str(self.root),
|
||||
"-B", str(build_dir),
|
||||
f'''-DCMAKE_C_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
|
||||
f'''-DCMAKE_CXX_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
|
||||
# NDK 21e does not support -ffile-prefix-map
|
||||
# f'''-DCMAKE_C_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
|
||||
# f'''-DCMAKE_CXX_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''',
|
||||
f"-DCMAKE_EXE_LINKER_FLAGS={extra_link_options}",
|
||||
f"-DCMAKE_SHARED_LINKER_FLAGS={extra_link_options}",
|
||||
f"-DCMAKE_TOOLCHAIN_FILE={cmake_toolchain_file}",
|
||||
f"-DCMAKE_PREFIX_PATH={str(android_deps_path)}",
|
||||
f"-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH",
|
||||
@@ -1530,7 +1535,7 @@ def main(argv=None) -> int:
|
||||
parser.error("Invalid --android-api, and/or could not be detected")
|
||||
android_api_path = Path(args.android_home) / f"platforms/{args.android_api.name}"
|
||||
if not android_api_path.is_dir():
|
||||
parser.error(f"Android API directory does not exist ({android_api_path})")
|
||||
logger.warning(f"Android API directory does not exist ({android_api_path})")
|
||||
with section_printer.group("Android arguments"):
|
||||
print(f"android_home = {args.android_home}")
|
||||
print(f"android_ndk_home = {args.android_ndk_home}")
|
||||
|
||||
Executable
+127
@@ -0,0 +1,127 @@
|
||||
#!/bin/bash
|
||||
progname="${0##*/}"
|
||||
progname="${progname%.sh}"
|
||||
|
||||
# usage: check_elf_alignment.sh [path to *.so files|path to *.apk]
|
||||
|
||||
cleanup_trap() {
|
||||
if [ -n "${tmp}" -a -d "${tmp}" ]; then
|
||||
rm -rf ${tmp}
|
||||
fi
|
||||
exit $1
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "Host side script to check the ELF alignment of shared libraries."
|
||||
echo "Shared libraries are reported ALIGNED when their ELF regions are"
|
||||
echo "16 KB or 64 KB aligned. Otherwise they are reported as UNALIGNED."
|
||||
echo
|
||||
echo "Usage: ${progname} [input-path|input-APK|input-APEX]"
|
||||
}
|
||||
|
||||
if [ ${#} -ne 1 ]; then
|
||||
usage
|
||||
exit
|
||||
fi
|
||||
|
||||
case ${1} in
|
||||
--help | -h | -\?)
|
||||
usage
|
||||
exit
|
||||
;;
|
||||
|
||||
*)
|
||||
dir="${1}"
|
||||
;;
|
||||
esac
|
||||
|
||||
if ! [ -f "${dir}" -o -d "${dir}" ]; then
|
||||
echo "Invalid file: ${dir}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${dir}" == *.apk ]]; then
|
||||
trap 'cleanup_trap' EXIT
|
||||
|
||||
echo
|
||||
echo "Recursively analyzing $dir"
|
||||
echo
|
||||
|
||||
if { zipalign --help 2>&1 | grep -q "\-P <pagesize_kb>"; }; then
|
||||
echo "=== APK zip-alignment ==="
|
||||
zipalign -v -c -P 16 4 "${dir}" | egrep 'lib/arm64-v8a|lib/x86_64|Verification'
|
||||
echo "========================="
|
||||
else
|
||||
echo "NOTICE: Zip alignment check requires build-tools version 35.0.0-rc3 or higher."
|
||||
echo " You can install the latest build-tools by running the below command"
|
||||
echo " and updating your \$PATH:"
|
||||
echo
|
||||
echo " sdkmanager \"build-tools;35.0.0-rc3\""
|
||||
fi
|
||||
|
||||
dir_filename=$(basename "${dir}")
|
||||
tmp=$(mktemp -d -t "${dir_filename%.apk}_out_XXXXX")
|
||||
unzip "${dir}" lib/* -d "${tmp}" >/dev/null 2>&1
|
||||
dir="${tmp}"
|
||||
fi
|
||||
|
||||
if [[ "${dir}" == *.apex ]]; then
|
||||
trap 'cleanup_trap' EXIT
|
||||
|
||||
echo
|
||||
echo "Recursively analyzing $dir"
|
||||
echo
|
||||
|
||||
dir_filename=$(basename "${dir}")
|
||||
tmp=$(mktemp -d -t "${dir_filename%.apex}_out_XXXXX")
|
||||
deapexer extract "${dir}" "${tmp}" || { echo "Failed to deapex." && exit 1; }
|
||||
dir="${tmp}"
|
||||
fi
|
||||
|
||||
RED="\e[31m"
|
||||
GREEN="\e[32m"
|
||||
ENDCOLOR="\e[0m"
|
||||
|
||||
unaligned_libs=()
|
||||
unaligned_critical_libs=()
|
||||
|
||||
echo
|
||||
echo "=== ELF alignment ==="
|
||||
|
||||
matches="$(find "${dir}" -type f)"
|
||||
IFS=$'\n'
|
||||
for match in $matches; do
|
||||
# We could recursively call this script or rewrite it to though.
|
||||
[[ "${match}" == *".apk" ]] && echo "WARNING: doesn't recursively inspect .apk file: ${match}"
|
||||
[[ "${match}" == *".apex" ]] && echo "WARNING: doesn't recursively inspect .apex file: ${match}"
|
||||
|
||||
[[ $(file "${match}") == *"ELF"* ]] || continue
|
||||
|
||||
res="$(objdump -p "${match}" | grep LOAD | awk '{ print $NF }' | head -1)"
|
||||
if [[ $res =~ 2\*\*(1[4-9]|[2-9][0-9]|[1-9][0-9]{2,}) ]]; then
|
||||
echo -e "${match}: ${GREEN}ALIGNED${ENDCOLOR} ($res)"
|
||||
else
|
||||
unaligned_libs+=("${match}")
|
||||
# Check if this is a critical architecture (arm64-v8a or x86_64)
|
||||
if [[ "${match}" == *"arm64-v8a"* ]] || [[ "${match}" == *"x86_64"* ]]; then
|
||||
unaligned_critical_libs+=("${match}")
|
||||
echo -e "${match}: ${RED}UNALIGNED${ENDCOLOR} ($res)"
|
||||
else
|
||||
echo -e "${match}: UNALIGNED ($res)"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#unaligned_libs[@]} -gt 0 ]; then
|
||||
echo -e "Found ${#unaligned_libs[@]} unaligned libs (only arm64-v8a/x86_64 libs need to be aligned).${ENDCOLOR}"
|
||||
fi
|
||||
echo "====================="
|
||||
|
||||
# Exit with appropriate code: 1 if critical unaligned libs found, 0 otherwise
|
||||
if [ ${#unaligned_critical_libs[@]} -gt 0 ]; then
|
||||
echo -e "${RED}Found ${#unaligned_critical_libs[@]} critical unaligned libs.${ENDCOLOR}"
|
||||
exit 1
|
||||
else
|
||||
echo -e "${GREEN}ELF Verification Successful${ENDCOLOR}"
|
||||
exit 0
|
||||
fi
|
||||
@@ -183,7 +183,7 @@
|
||||
],
|
||||
"api-minimum": 21,
|
||||
"api-target": 35,
|
||||
"ndk-minimum": 21,
|
||||
"ndk-minimum": 28,
|
||||
"aar-files": {
|
||||
"": [
|
||||
"android-project/app/proguard-rules.pro:proguard.txt",
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# libtool assumes that the compiler can handle the -fPIC flag
|
||||
# This isn't always true (for example, nasm can't handle it)
|
||||
command=""
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-?PIC)
|
||||
# Ignore -fPIC and -DPIC options
|
||||
;;
|
||||
-fno-common)
|
||||
# Ignore -fPIC and -DPIC options
|
||||
;;
|
||||
*)
|
||||
command="$command $1"
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
echo $command
|
||||
exec $command
|
||||
@@ -1,16 +1,21 @@
|
||||
# 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)
|
||||
if(MINGW)
|
||||
set(re_shared_suffix ".dll.a$")
|
||||
else()
|
||||
set(re_shared_suffix "${CMAKE_SHARED_LIBRARY_SUFFIX}$")
|
||||
endif()
|
||||
if("${_library}" MATCHES "${re_shared_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
|
||||
|
||||
@@ -1077,6 +1077,14 @@ endmacro()
|
||||
|
||||
# Check for HIDAPI support
|
||||
macro(CheckHIDAPI)
|
||||
if(ANDROID)
|
||||
enable_language(CXX)
|
||||
sdl_sources("${SDL3_SOURCE_DIR}/src/hidapi/android/hid.cpp")
|
||||
endif()
|
||||
if(IOS OR TVOS)
|
||||
sdl_sources("${SDL3_SOURCE_DIR}/src/hidapi/ios/hid.m")
|
||||
set(SDL_FRAMEWORK_COREBLUETOOTH 1)
|
||||
endif()
|
||||
if(SDL_HIDAPI)
|
||||
set(HAVE_HIDAPI ON)
|
||||
if(SDL_HIDAPI_LIBUSB)
|
||||
@@ -1109,14 +1117,6 @@ macro(CheckHIDAPI)
|
||||
endif()
|
||||
|
||||
if(HAVE_HIDAPI)
|
||||
if(ANDROID)
|
||||
enable_language(CXX)
|
||||
sdl_sources("${SDL3_SOURCE_DIR}/src/hidapi/android/hid.cpp")
|
||||
endif()
|
||||
if(IOS OR TVOS)
|
||||
sdl_sources("${SDL3_SOURCE_DIR}/src/hidapi/ios/hid.m")
|
||||
set(SDL_FRAMEWORK_COREBLUETOOTH 1)
|
||||
endif()
|
||||
set(HAVE_SDL_HIDAPI TRUE)
|
||||
|
||||
if(SDL_JOYSTICK AND SDL_HIDAPI_JOYSTICK)
|
||||
|
||||
@@ -160,3 +160,63 @@ function(SDL_AddCommonCompilerFlags TARGET)
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(check_x86_source_compiles BODY VAR)
|
||||
if(ARGN)
|
||||
message(FATAL_ERROR "Unknown arguments: ${ARGN}")
|
||||
endif()
|
||||
if(APPLE_MULTIARCH AND (SDL_CPU_X86 OR SDL_CPU_X64))
|
||||
set(test_conditional 1)
|
||||
else()
|
||||
set(test_conditional 0)
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
#if ${test_conditional}
|
||||
# if defined(__i386__) || defined(__x86_64__)
|
||||
# define test_enabled 1
|
||||
# else
|
||||
# define test_enabled 0 /* feign success in Apple multi-arch configs */
|
||||
# endif
|
||||
#else /* test normally */
|
||||
# define test_enabled 1
|
||||
#endif
|
||||
#if test_enabled
|
||||
${BODY}
|
||||
#else
|
||||
int main(int argc, char *argv[]) {
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
return 0;
|
||||
}
|
||||
#endif" ${VAR})
|
||||
endfunction()
|
||||
|
||||
function(check_arm_source_compiles BODY VAR)
|
||||
if(ARGN)
|
||||
message(FATAL_ERROR "Unknown arguments: ${ARGN}")
|
||||
endif()
|
||||
if(APPLE_MULTIARCH AND (SDL_CPU_ARM32 OR SDL_CPU_ARM64))
|
||||
set(test_conditional 1)
|
||||
else()
|
||||
set(test_conditional 0)
|
||||
endif()
|
||||
check_c_source_compiles("
|
||||
#if ${test_conditional}
|
||||
# if defined(__arm__) || defined(__aarch64__)
|
||||
# define test_enabled 1
|
||||
# else
|
||||
# define test_enabled 0 /* feign success in Apple multi-arch configs */
|
||||
# endif
|
||||
#else /* test normally */
|
||||
# define test_enabled 1
|
||||
#endif
|
||||
#if test_enabled
|
||||
${BODY}
|
||||
#else
|
||||
int main(int argc, char *argv[]) {
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
return 0;
|
||||
}
|
||||
#endif" ${VAR})
|
||||
endfunction()
|
||||
+3
-3
@@ -4,15 +4,15 @@ function(SDL_DetectTargetCPUArchitectures DETECTED_ARCHS)
|
||||
|
||||
if(APPLE AND CMAKE_OSX_ARCHITECTURES)
|
||||
foreach(known_arch IN LISTS known_archs)
|
||||
set(SDL_CPU_${known_arch} "0")
|
||||
set(SDL_CPU_${known_arch} "0" PARENT_SCOPE)
|
||||
endforeach()
|
||||
set(detected_archs)
|
||||
foreach(osx_arch IN LISTS CMAKE_OSX_ARCHITECTURES)
|
||||
if(osx_arch STREQUAL "x86_64")
|
||||
set(SDL_CPU_X64 "1")
|
||||
set(SDL_CPU_X64 "1" PARENT_SCOPE)
|
||||
list(APPEND detected_archs "X64")
|
||||
elseif(osx_arch STREQUAL "arm64")
|
||||
set(SDL_CPU_ARM64 "1")
|
||||
set(SDL_CPU_ARM64 "1" PARENT_SCOPE)
|
||||
list(APPEND detected_archs "ARM64")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
@@ -131,7 +131,7 @@ function(sdl_compile_options)
|
||||
target_compile_options(SDL3-static ${visibility} ${escaped_opts})
|
||||
endif()
|
||||
if(NOT ARGS_NO_EXPORT AND (ARGS_PUBLIC OR ARGS_INTERFACE))
|
||||
set_property(TARGET SDL3-collector APPEND PROPERTY INTERFACE_COMPILE_COMPILE_OPTIONS "${ARGS_UNPARSED_ARGUMENTS}")
|
||||
set_property(TARGET SDL3-collector APPEND PROPERTY INTERFACE_COMPILE_OPTIONS "${ARGS_UNPARSED_ARGUMENTS}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ NSApplicationDelegate implementation:
|
||||
```objc
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
|
||||
{
|
||||
if (SDL_GetEventState(SDL_EVENT_QUIT) == SDL_ENABLE) {
|
||||
if (SDL_EventEnabled(SDL_EVENT_QUIT)) {
|
||||
SDL_Event event;
|
||||
SDL_zero(event);
|
||||
event.type = SDL_EVENT_QUIT;
|
||||
@@ -61,7 +61,7 @@ NSApplicationDelegate implementation:
|
||||
|
||||
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
|
||||
{
|
||||
if (SDL_GetEventState(SDL_EVENT_DROP_FILE) == SDL_ENABLE) {
|
||||
if (SDL_EventEnabled(SDL_EVENT_DROP_FILE)) {
|
||||
SDL_Event event;
|
||||
SDL_zero(event);
|
||||
event.type = SDL_EVENT_DROP_FILE;
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Main include header for the SDL library, version 3.2.16
|
||||
* Main include header for the SDL library, version 3.2.26
|
||||
*
|
||||
* It is almost always best to include just this one header instead of
|
||||
* picking out individual headers included here. There are exceptions to
|
||||
|
||||
@@ -126,7 +126,7 @@ extern "C" {
|
||||
*/
|
||||
#define SDL_TriggerBreakpoint() TriggerABreakpointInAPlatformSpecificManner
|
||||
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1310
|
||||
#elif defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER >= 1310)
|
||||
/* Don't include intrin.h here because it contains C++ code */
|
||||
extern void __cdecl __debugbreak(void);
|
||||
#define SDL_TriggerBreakpoint() __debugbreak()
|
||||
@@ -362,7 +362,7 @@ extern SDL_DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *
|
||||
#define SDL_enabled_assert(condition) \
|
||||
do { \
|
||||
while ( !(condition) ) { \
|
||||
static struct SDL_AssertData sdl_assert_data = { 0, 0, #condition, 0, 0, 0, 0 }; \
|
||||
static struct SDL_AssertData sdl_assert_data = { false, 0, #condition, NULL, 0, NULL, NULL }; \
|
||||
const SDL_AssertState sdl_assert_state = SDL_ReportAssertion(&sdl_assert_data, SDL_FUNCTION, SDL_FILE, SDL_LINE); \
|
||||
if (sdl_assert_state == SDL_ASSERTION_RETRY) { \
|
||||
continue; /* go again. */ \
|
||||
|
||||
@@ -942,7 +942,10 @@ extern SDL_DECLSPEC void SDLCALL SDL_CloseAudioDevice(SDL_AudioDeviceID devid);
|
||||
* Binding a stream to a device will set its output format for playback
|
||||
* devices, and its input format for recording devices, so they match the
|
||||
* device's settings. The caller is welcome to change the other end of the
|
||||
* stream's format at any time with SDL_SetAudioStreamFormat().
|
||||
* stream's format at any time with SDL_SetAudioStreamFormat(). If the other
|
||||
* end of the stream's format has never been set (the audio stream was created
|
||||
* with a NULL audio spec), this function will set it to match the device
|
||||
* end's format.
|
||||
*
|
||||
* \param devid an audio device to bind a stream to.
|
||||
* \param streams an array of audio streams to bind.
|
||||
@@ -1021,7 +1024,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_UnbindAudioStream(SDL_AudioStream *stream);
|
||||
/**
|
||||
* Query an audio stream for its currently-bound device.
|
||||
*
|
||||
* This reports the audio device that an audio stream is currently bound to.
|
||||
* This reports the logical audio device that an audio stream is currently bound to.
|
||||
*
|
||||
* If not bound, or invalid, this returns zero, which is not a valid device
|
||||
* ID.
|
||||
|
||||
@@ -119,7 +119,7 @@ typedef struct SDL_CameraSpec
|
||||
int width; /**< Frame width */
|
||||
int height; /**< Frame height */
|
||||
int framerate_numerator; /**< Frame rate numerator ((num / denom) == FPS, (denom / num) == duration in seconds) */
|
||||
int framerate_denominator; /**< Frame rate demoninator ((num / denom) == FPS, (denom / num) == duration in seconds) */
|
||||
int framerate_denominator; /**< Frame rate denominator ((num / denom) == FPS, (denom / num) == duration in seconds) */
|
||||
} SDL_CameraSpec;
|
||||
|
||||
/**
|
||||
|
||||
@@ -106,7 +106,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetClipboardText(const char *text);
|
||||
/**
|
||||
* Get UTF-8 text from the clipboard.
|
||||
*
|
||||
* This functions returns an empty string if there was not enough memory left
|
||||
* This function returns an empty string if there is not enough memory left
|
||||
* for a copy of the clipboard's content.
|
||||
*
|
||||
* \returns the clipboard text on success or an empty string on failure; call
|
||||
@@ -155,7 +155,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetPrimarySelectionText(const char *text);
|
||||
/**
|
||||
* Get UTF-8 text from the primary selection.
|
||||
*
|
||||
* This functions returns an empty string if there was not enough memory left
|
||||
* This function returns an empty string if there is not enough memory left
|
||||
* for a copy of the primary selection's content.
|
||||
*
|
||||
* \returns the primary selection text on success or an empty string on
|
||||
@@ -194,15 +194,14 @@ extern SDL_DECLSPEC bool SDLCALL SDL_HasPrimarySelectionText(void);
|
||||
* clipboard is cleared or new data is set. The clipboard is automatically
|
||||
* cleared in SDL_Quit().
|
||||
*
|
||||
* \param userdata a pointer to provided user data.
|
||||
* \param userdata a pointer to the provided user data.
|
||||
* \param mime_type the requested mime-type.
|
||||
* \param size a pointer filled in with the length of the returned data.
|
||||
* \returns a pointer to the data for the provided mime-type. Returning NULL
|
||||
* or setting length to 0 will cause no data to be sent to the
|
||||
* "receiver". It is up to the receiver to handle this. Essentially
|
||||
* returning no data is more or less undefined behavior and may cause
|
||||
* breakage in receiving applications. The returned data will not be
|
||||
* freed so it needs to be retained and dealt with internally.
|
||||
* or setting the length to 0 will cause zero length data to be sent
|
||||
* to the "receiver", which should be able to handle this. The
|
||||
* returned data will not be freed, so it needs to be retained and
|
||||
* dealt with internally.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
@@ -211,10 +210,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_HasPrimarySelectionText(void);
|
||||
typedef const void *(SDLCALL *SDL_ClipboardDataCallback)(void *userdata, const char *mime_type, size_t *size);
|
||||
|
||||
/**
|
||||
* Callback function that will be called when the clipboard is cleared, or new
|
||||
* Callback function that will be called when the clipboard is cleared, or when new
|
||||
* data is set.
|
||||
*
|
||||
* \param userdata a pointer to provided user data.
|
||||
* \param userdata a pointer to the provided user data.
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*
|
||||
@@ -231,7 +230,7 @@ typedef void (SDLCALL *SDL_ClipboardCleanupCallback)(void *userdata);
|
||||
* respond with the data for the requested mime-type.
|
||||
*
|
||||
* The size of text data does not include any terminator, and the text does
|
||||
* not need to be null terminated (e.g. you can directly copy a portion of a
|
||||
* not need to be null-terminated (e.g., you can directly copy a portion of a
|
||||
* document).
|
||||
*
|
||||
* \param callback a function pointer to the function that provides the
|
||||
@@ -239,7 +238,7 @@ typedef void (SDLCALL *SDL_ClipboardCleanupCallback)(void *userdata);
|
||||
* \param cleanup a function pointer to the function that cleans up the
|
||||
* clipboard data.
|
||||
* \param userdata an opaque pointer that will be forwarded to the callbacks.
|
||||
* \param mime_types a list of mime-types that are being offered.
|
||||
* \param mime_types a list of mime-types that are being offered. SDL copies the given list.
|
||||
* \param num_mime_types the number of mime-types in the mime_types list.
|
||||
* \returns true on success or false on failure; call SDL_GetError() for more
|
||||
* information.
|
||||
@@ -269,10 +268,10 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetClipboardData(SDL_ClipboardDataCallback
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_ClearClipboardData(void);
|
||||
|
||||
/**
|
||||
* Get the data from clipboard for a given mime type.
|
||||
* Get the data from the clipboard for a given mime type.
|
||||
*
|
||||
* The size of text data does not include the terminator, but the text is
|
||||
* guaranteed to be null terminated.
|
||||
* guaranteed to be null-terminated.
|
||||
*
|
||||
* \param mime_type the mime type to read from the clipboard.
|
||||
* \param size a pointer filled in with the length of the returned data.
|
||||
@@ -292,8 +291,8 @@ extern SDL_DECLSPEC void * SDLCALL SDL_GetClipboardData(const char *mime_type, s
|
||||
/**
|
||||
* Query whether there is data in the clipboard for the provided mime type.
|
||||
*
|
||||
* \param mime_type the mime type to check for data for.
|
||||
* \returns true if there exists data in clipboard for the provided mime type,
|
||||
* \param mime_type the mime type to check for data.
|
||||
* \returns true if data exists in the clipboard for the provided mime type,
|
||||
* false if it does not.
|
||||
*
|
||||
* \threadsafety This function should only be called on the main thread.
|
||||
@@ -310,7 +309,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_HasClipboardData(const char *mime_type);
|
||||
*
|
||||
* \param num_mime_types a pointer filled with the number of mime types, may
|
||||
* be NULL.
|
||||
* \returns a null terminated array of strings with mime types, or NULL on
|
||||
* \returns a null-terminated array of strings with mime types, or NULL on
|
||||
* failure; call SDL_GetError() for more information. This should be
|
||||
* freed with SDL_free() when it is no longer needed.
|
||||
*
|
||||
|
||||
@@ -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__))
|
||||
@@ -128,7 +128,7 @@ _m_prefetch(void *__P)
|
||||
* \sa SDL_BIG_ENDIAN
|
||||
*/
|
||||
#define SDL_BYTEORDER SDL_LIL_ENDIAN___or_maybe___SDL_BIG_ENDIAN
|
||||
#elif defined(SDL_PLATFORM_LINUX)
|
||||
#elif defined(SDL_PLATFORM_LINUX) || defined(__GLIBC__)
|
||||
#include <endian.h>
|
||||
#define SDL_BYTEORDER __BYTE_ORDER
|
||||
#elif defined(SDL_PLATFORM_SOLARIS)
|
||||
@@ -486,7 +486,7 @@ SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x) { return x_but_byteswapped; }
|
||||
*
|
||||
* \since This function is available since SDL 3.2.0.
|
||||
*/
|
||||
SDL_FORCE_INLINE Uint32 SDL_Swap64(Uint64 x) { return x_but_byteswapped; }
|
||||
SDL_FORCE_INLINE Uint64 SDL_Swap64(Uint64 x) { return x_but_byteswapped; }
|
||||
|
||||
/**
|
||||
* Swap a 16-bit value from littleendian to native byte order.
|
||||
|
||||
@@ -1043,7 +1043,7 @@ typedef union SDL_Event
|
||||
} SDL_Event;
|
||||
|
||||
/* Make sure we haven't broken binary compatibility */
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_Event, sizeof(SDL_Event) == sizeof(((SDL_Event *)NULL)->padding));
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_Event, sizeof(SDL_Event) == sizeof((SDL_static_cast(SDL_Event *, NULL))->padding));
|
||||
|
||||
|
||||
/* Function prototypes */
|
||||
|
||||
@@ -224,8 +224,8 @@
|
||||
* - `drawIndirectFirstInstance`
|
||||
*
|
||||
* **D3D12:** Supported on Windows 10 or newer, Xbox One (GDK), and Xbox
|
||||
* Series X|S (GDK). Requires a GPU that supports DirectX 12 Feature Level
|
||||
* 11_1.
|
||||
* Series X|S (GDK). Requires a GPU that supports DirectX 12 Feature Level 11_0 and
|
||||
* Resource Binding Tier 2 or above.
|
||||
*
|
||||
* **Metal:** Supported on macOS 10.14+ and iOS/tvOS 13.0+. Hardware
|
||||
* requirements vary by operating system:
|
||||
@@ -1091,7 +1091,7 @@ typedef enum SDL_GPUCompareOp
|
||||
SDL_GPU_COMPAREOP_LESS_OR_EQUAL, /**< The comparison evaluates reference <= test. */
|
||||
SDL_GPU_COMPAREOP_GREATER, /**< The comparison evaluates reference > test. */
|
||||
SDL_GPU_COMPAREOP_NOT_EQUAL, /**< The comparison evaluates reference != test. */
|
||||
SDL_GPU_COMPAREOP_GREATER_OR_EQUAL, /**< The comparison evalutes reference >= test. */
|
||||
SDL_GPU_COMPAREOP_GREATER_OR_EQUAL, /**< The comparison evaluates reference >= test. */
|
||||
SDL_GPU_COMPAREOP_ALWAYS /**< The comparison always evaluates true. */
|
||||
} SDL_GPUCompareOp;
|
||||
|
||||
@@ -1549,7 +1549,7 @@ typedef struct SDL_GPUSamplerCreateInfo
|
||||
typedef struct SDL_GPUVertexBufferDescription
|
||||
{
|
||||
Uint32 slot; /**< The binding slot of the vertex buffer. */
|
||||
Uint32 pitch; /**< The byte pitch between consecutive elements of the vertex buffer. */
|
||||
Uint32 pitch; /**< The size of a single element + the offset between elements. */
|
||||
SDL_GPUVertexInputRate input_rate; /**< Whether attribute addressing is a function of the vertex index or instance index. */
|
||||
Uint32 instance_step_rate; /**< Reserved for future use. Must be set to 0. */
|
||||
} SDL_GPUVertexBufferDescription;
|
||||
@@ -2648,7 +2648,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_InsertGPUDebugLabel(
|
||||
const char *text);
|
||||
|
||||
/**
|
||||
* Begins a debug group with an arbitary name.
|
||||
* Begins a debug group with an arbitrary name.
|
||||
*
|
||||
* Used for denoting groups of calls when viewing the command buffer
|
||||
* callstream in a graphics debugging tool.
|
||||
|
||||
@@ -595,7 +595,7 @@ extern "C" {
|
||||
* A variable that limits what CPU features are available.
|
||||
*
|
||||
* By default, SDL marks all features the current CPU supports as available.
|
||||
* This hint allows to limit these to a subset.
|
||||
* This hint allows the enabled features to be limited to a subset.
|
||||
*
|
||||
* When the hint is unset, or empty, SDL will enable all detected CPU
|
||||
* features.
|
||||
@@ -2126,8 +2126,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.
|
||||
*
|
||||
|
||||
@@ -360,7 +360,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_LockMutex(SDL_Mutex *mutex) SDL_ACQUIRE(mut
|
||||
* \sa SDL_LockMutex
|
||||
* \sa SDL_UnlockMutex
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_TryLockMutex(SDL_Mutex *mutex) SDL_TRY_ACQUIRE(0, mutex);
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_TryLockMutex(SDL_Mutex *mutex) SDL_TRY_ACQUIRE(true, mutex);
|
||||
|
||||
/**
|
||||
* Unlock the mutex.
|
||||
@@ -559,7 +559,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_LockRWLockForWriting(SDL_RWLock *rwlock) SD
|
||||
* \sa SDL_TryLockRWLockForWriting
|
||||
* \sa SDL_UnlockRWLock
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_TryLockRWLockForReading(SDL_RWLock *rwlock) SDL_TRY_ACQUIRE_SHARED(0, rwlock);
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_TryLockRWLockForReading(SDL_RWLock *rwlock) SDL_TRY_ACQUIRE_SHARED(true, rwlock);
|
||||
|
||||
/**
|
||||
* Try to lock a read/write lock _for writing_ without blocking.
|
||||
@@ -589,7 +589,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_TryLockRWLockForReading(SDL_RWLock *rwlock)
|
||||
* \sa SDL_TryLockRWLockForReading
|
||||
* \sa SDL_UnlockRWLock
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_TryLockRWLockForWriting(SDL_RWLock *rwlock) SDL_TRY_ACQUIRE(0, rwlock);
|
||||
extern SDL_DECLSPEC bool SDLCALL SDL_TryLockRWLockForWriting(SDL_RWLock *rwlock) SDL_TRY_ACQUIRE(true, rwlock);
|
||||
|
||||
/**
|
||||
* Unlock the read/write lock.
|
||||
|
||||
@@ -125,10 +125,10 @@ typedef struct SDL_FRect
|
||||
*/
|
||||
SDL_FORCE_INLINE void SDL_RectToFRect(const SDL_Rect *rect, SDL_FRect *frect)
|
||||
{
|
||||
frect->x = (float)rect->x;
|
||||
frect->y = (float)rect->y;
|
||||
frect->w = (float)rect->w;
|
||||
frect->h = (float)rect->h;
|
||||
frect->x = SDL_static_cast(float, rect->x);
|
||||
frect->y = SDL_static_cast(float, rect->y);
|
||||
frect->w = SDL_static_cast(float, rect->w);
|
||||
frect->h = SDL_static_cast(float, rect->h);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2612,7 +2612,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_RenderDebugText(SDL_Renderer *renderer, flo
|
||||
* Draw debug text to an SDL_Renderer.
|
||||
*
|
||||
* This function will render a printf()-style format string to a renderer.
|
||||
* Note that this is a convinence function for debugging, with severe
|
||||
* Note that this is a convenience function for debugging, with severe
|
||||
* limitations, and is not intended to be used for production apps and games.
|
||||
*
|
||||
* For the full list of limitations and other useful information, see
|
||||
|
||||
@@ -208,7 +208,7 @@ typedef enum SDL_Scancode
|
||||
|
||||
SDL_SCANCODE_NONUSBACKSLASH = 100, /**< This is the additional key that ISO
|
||||
* keyboards have over ANSI ones,
|
||||
* located between left shift and Y.
|
||||
* located between left shift and Z.
|
||||
* Produces GRAVE ACCENT and TILDE in a
|
||||
* US or UK Mac layout, REVERSE SOLIDUS
|
||||
* (backslash) and VERTICAL LINE in a
|
||||
|
||||
@@ -138,7 +138,8 @@ typedef enum SDL_SensorType
|
||||
SDL_SENSOR_ACCEL_L, /**< Accelerometer for left Joy-Con controller and Wii nunchuk */
|
||||
SDL_SENSOR_GYRO_L, /**< Gyroscope for left Joy-Con controller */
|
||||
SDL_SENSOR_ACCEL_R, /**< Accelerometer for right Joy-Con controller */
|
||||
SDL_SENSOR_GYRO_R /**< Gyroscope for right Joy-Con controller */
|
||||
SDL_SENSOR_GYRO_R, /**< Gyroscope for right Joy-Con controller */
|
||||
SDL_SENSOR_COUNT
|
||||
} SDL_SensorType;
|
||||
|
||||
|
||||
|
||||
+13
-13
@@ -1164,7 +1164,7 @@ typedef struct SDL_alignment_test
|
||||
void *b;
|
||||
} SDL_alignment_test;
|
||||
SDL_COMPILE_TIME_ASSERT(struct_alignment, sizeof(SDL_alignment_test) == (2 * sizeof(void *)));
|
||||
SDL_COMPILE_TIME_ASSERT(two_s_complement, (int)~(int)0 == (int)(-1));
|
||||
SDL_COMPILE_TIME_ASSERT(two_s_complement, SDL_static_cast(int, ~SDL_static_cast(int, 0)) == SDL_static_cast(int, -1));
|
||||
#endif /* DOXYGEN_SHOULD_IGNORE_THIS */
|
||||
/** \endcond */
|
||||
|
||||
@@ -3426,7 +3426,7 @@ extern SDL_DECLSPEC size_t SDLCALL SDL_utf8strnlen(const char *str, size_t bytes
|
||||
* Convert an integer into a string.
|
||||
*
|
||||
* This requires a radix to specified for string format. Specifying 10
|
||||
* produces a decimal number, 16 hexidecimal, etc. Must be in the range of 2
|
||||
* produces a decimal number, 16 hexadecimal, etc. Must be in the range of 2
|
||||
* to 36.
|
||||
*
|
||||
* Note that this function will overflow a buffer if `str` is not large enough
|
||||
@@ -3454,7 +3454,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_itoa(int value, char *str, int radix);
|
||||
* Convert an unsigned integer into a string.
|
||||
*
|
||||
* This requires a radix to specified for string format. Specifying 10
|
||||
* produces a decimal number, 16 hexidecimal, etc. Must be in the range of 2
|
||||
* produces a decimal number, 16 hexadecimal, etc. Must be in the range of 2
|
||||
* to 36.
|
||||
*
|
||||
* Note that this function will overflow a buffer if `str` is not large enough
|
||||
@@ -3482,7 +3482,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_uitoa(unsigned int value, char *str, int
|
||||
* Convert a long integer into a string.
|
||||
*
|
||||
* This requires a radix to specified for string format. Specifying 10
|
||||
* produces a decimal number, 16 hexidecimal, etc. Must be in the range of 2
|
||||
* produces a decimal number, 16 hexadecimal, etc. Must be in the range of 2
|
||||
* to 36.
|
||||
*
|
||||
* Note that this function will overflow a buffer if `str` is not large enough
|
||||
@@ -3510,7 +3510,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_ltoa(long value, char *str, int radix);
|
||||
* Convert an unsigned long integer into a string.
|
||||
*
|
||||
* This requires a radix to specified for string format. Specifying 10
|
||||
* produces a decimal number, 16 hexidecimal, etc. Must be in the range of 2
|
||||
* produces a decimal number, 16 hexadecimal, etc. Must be in the range of 2
|
||||
* to 36.
|
||||
*
|
||||
* Note that this function will overflow a buffer if `str` is not large enough
|
||||
@@ -3540,7 +3540,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_ultoa(unsigned long value, char *str, int
|
||||
* Convert a long long integer into a string.
|
||||
*
|
||||
* This requires a radix to specified for string format. Specifying 10
|
||||
* produces a decimal number, 16 hexidecimal, etc. Must be in the range of 2
|
||||
* produces a decimal number, 16 hexadecimal, etc. Must be in the range of 2
|
||||
* to 36.
|
||||
*
|
||||
* Note that this function will overflow a buffer if `str` is not large enough
|
||||
@@ -3568,7 +3568,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_lltoa(long long value, char *str, int rad
|
||||
* Convert an unsigned long long integer into a string.
|
||||
*
|
||||
* This requires a radix to specified for string format. Specifying 10
|
||||
* produces a decimal number, 16 hexidecimal, etc. Must be in the range of 2
|
||||
* produces a decimal number, 16 hexadecimal, etc. Must be in the range of 2
|
||||
* to 36.
|
||||
*
|
||||
* Note that this function will overflow a buffer if `str` is not large enough
|
||||
@@ -3923,7 +3923,7 @@ extern SDL_DECLSPEC int SDLCALL SDL_strcasecmp(const char *str1, const char *str
|
||||
extern SDL_DECLSPEC int SDLCALL SDL_strncasecmp(const char *str1, const char *str2, size_t maxlen);
|
||||
|
||||
/**
|
||||
* Searches a string for the first occurence of any character contained in a
|
||||
* Searches a string for the first occurrence of any character contained in a
|
||||
* breakset, and returns a pointer from the string to that character.
|
||||
*
|
||||
* \param str The null-terminated string to be searched. Must not be NULL, and
|
||||
@@ -3931,7 +3931,7 @@ extern SDL_DECLSPEC int SDLCALL SDL_strncasecmp(const char *str1, const char *st
|
||||
* \param breakset A null-terminated string containing the list of characters
|
||||
* to look for. Must not be NULL, and must not overlap with
|
||||
* `str`.
|
||||
* \returns A pointer to the location, in str, of the first occurence of a
|
||||
* \returns A pointer to the location, in str, of the first occurrence of a
|
||||
* character present in the breakset, or NULL if none is found.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
@@ -5821,7 +5821,7 @@ extern SDL_DECLSPEC int SDLCALL SDL_iconv_close(SDL_iconv_t cd);
|
||||
* This function converts text between encodings, reading from and writing to
|
||||
* a buffer.
|
||||
*
|
||||
* It returns the number of succesful conversions on success. On error,
|
||||
* It returns the number of successful conversions on success. On error,
|
||||
* SDL_ICONV_E2BIG is returned when the output buffer is too small, or
|
||||
* SDL_ICONV_EILSEQ is returned when an invalid input sequence is encountered,
|
||||
* or SDL_ICONV_EINVAL is returned when an incomplete input sequence is
|
||||
@@ -5921,7 +5921,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_iconv_string(const char *tocode,
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_iconv_utf8_ucs2(S) (Uint16 *)SDL_iconv_string("UCS-2", "UTF-8", S, SDL_strlen(S)+1)
|
||||
#define SDL_iconv_utf8_ucs2(S) SDL_reinterpret_cast(Uint16 *, SDL_iconv_string("UCS-2", "UTF-8", S, SDL_strlen(S)+1))
|
||||
|
||||
/**
|
||||
* Convert a UTF-8 string to UCS-4.
|
||||
@@ -5935,7 +5935,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_iconv_string(const char *tocode,
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_iconv_utf8_ucs4(S) (Uint32 *)SDL_iconv_string("UCS-4", "UTF-8", S, SDL_strlen(S)+1)
|
||||
#define SDL_iconv_utf8_ucs4(S) SDL_reinterpret_cast(Uint32 *, SDL_iconv_string("UCS-4", "UTF-8", S, SDL_strlen(S)+1))
|
||||
|
||||
/**
|
||||
* Convert a wchar_t string to UTF-8.
|
||||
@@ -5949,7 +5949,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_iconv_string(const char *tocode,
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_iconv_wchar_utf8(S) SDL_iconv_string("UTF-8", "WCHAR_T", (char *)S, (SDL_wcslen(S)+1)*sizeof(wchar_t))
|
||||
#define SDL_iconv_wchar_utf8(S) SDL_iconv_string("UTF-8", "WCHAR_T", SDL_reinterpret_cast(const char *, S), (SDL_wcslen(S)+1)*sizeof(wchar_t))
|
||||
|
||||
|
||||
/* force builds using Clang's static analysis tools to use literal C runtime
|
||||
|
||||
@@ -62,7 +62,7 @@ extern "C" {
|
||||
*
|
||||
* \since This macro is available since SDL 3.2.0.
|
||||
*/
|
||||
#define SDL_MICRO_VERSION 16
|
||||
#define SDL_MICRO_VERSION 26
|
||||
|
||||
/**
|
||||
* This macro turns the version numbers into a numeric value.
|
||||
|
||||
@@ -1167,6 +1167,15 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreateWindow(const char *title, int
|
||||
* Popup windows implicitly do not have a border/decorations and do not appear
|
||||
* on the taskbar/dock or in lists of windows such as alt-tab menus.
|
||||
*
|
||||
* By default, popup window positions will automatically be constrained to keep
|
||||
* the entire window within display bounds. This can be overridden with the
|
||||
* `SDL_PROP_WINDOW_CREATE_CONSTRAIN_POPUP_BOOLEAN` property.
|
||||
*
|
||||
* By default, popup menus will automatically grab keyboard focus from the parent
|
||||
* when shown. This behavior can be overridden by setting the `SDL_WINDOW_NOT_FOCUSABLE`
|
||||
* flag, setting the `SDL_PROP_WINDOW_CREATE_FOCUSABLE_BOOLEAN` property to false, or
|
||||
* toggling it after creation via the `SDL_SetWindowFocusable()` function.
|
||||
*
|
||||
* If a parent window is hidden or destroyed, any child popup windows will be
|
||||
* recursively hidden or destroyed as well. Child popup windows not explicitly
|
||||
* hidden will be restored when the parent is shown.
|
||||
@@ -1207,6 +1216,9 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreatePopupWindow(SDL_Window *paren
|
||||
* be always on top
|
||||
* - `SDL_PROP_WINDOW_CREATE_BORDERLESS_BOOLEAN`: true if the window has no
|
||||
* window decoration
|
||||
* - `SDL_PROP_WINDOW_CREATE_CONSTRAIN_POPUP_BOOLEAN`: true if the "tooltip" and
|
||||
* "menu" window types should be automatically constrained to be entirely within
|
||||
* display bounds (default), false if no constraints on the position are desired.
|
||||
* - `SDL_PROP_WINDOW_CREATE_EXTERNAL_GRAPHICS_CONTEXT_BOOLEAN`: true if the
|
||||
* window will be used with an externally managed graphics context.
|
||||
* - `SDL_PROP_WINDOW_CREATE_FOCUSABLE_BOOLEAN`: true if the window should
|
||||
@@ -1321,6 +1333,7 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_CreateWindowWithProperties(SDL_Prop
|
||||
|
||||
#define SDL_PROP_WINDOW_CREATE_ALWAYS_ON_TOP_BOOLEAN "SDL.window.create.always_on_top"
|
||||
#define SDL_PROP_WINDOW_CREATE_BORDERLESS_BOOLEAN "SDL.window.create.borderless"
|
||||
#define SDL_PROP_WINDOW_CREATE_CONSTRAIN_POPUP_BOOLEAN "SDL.window.create.constrain_popup"
|
||||
#define SDL_PROP_WINDOW_CREATE_FOCUSABLE_BOOLEAN "SDL.window.create.focusable"
|
||||
#define SDL_PROP_WINDOW_CREATE_EXTERNAL_GRAPHICS_CONTEXT_BOOLEAN "SDL.window.create.external_graphics_context"
|
||||
#define SDL_PROP_WINDOW_CREATE_FLAGS_NUMBER "SDL.window.create.flags"
|
||||
@@ -1460,7 +1473,7 @@ extern SDL_DECLSPEC SDL_Window * SDLCALL SDL_GetWindowParent(SDL_Window *window)
|
||||
* - `SDL_PROP_WINDOW_COCOA_WINDOW_POINTER`: the `(__unsafe_unretained)`
|
||||
* NSWindow associated with the window
|
||||
* - `SDL_PROP_WINDOW_COCOA_METAL_VIEW_TAG_NUMBER`: the NSInteger tag
|
||||
* assocated with metal views on the window
|
||||
* associated with metal views on the window
|
||||
*
|
||||
* On OpenVR:
|
||||
*
|
||||
|
||||
@@ -51,14 +51,14 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Avoid including vulkan.h, don't define VkInstance if it's already included */
|
||||
#ifdef VULKAN_H_
|
||||
/* Avoid including vulkan_core.h, don't define VkInstance if it's already included */
|
||||
#ifdef VULKAN_CORE_H_
|
||||
#define NO_SDL_VULKAN_TYPEDEFS
|
||||
#endif
|
||||
#ifndef NO_SDL_VULKAN_TYPEDEFS
|
||||
#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
|
||||
|
||||
#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
|
||||
#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) || (defined(__riscv) && __riscv_xlen == 64)
|
||||
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object;
|
||||
#else
|
||||
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object;
|
||||
|
||||
@@ -174,6 +174,7 @@
|
||||
#cmakedefine HAVE_MEMFD_CREATE 1
|
||||
#cmakedefine HAVE_POSIX_FALLOCATE 1
|
||||
#cmakedefine HAVE_SIGACTION 1
|
||||
#cmakedefine HAVE_SIGTIMEDWAIT 1
|
||||
#cmakedefine HAVE_SA_SIGACTION 1
|
||||
#cmakedefine HAVE_ST_MTIM 1
|
||||
#cmakedefine HAVE_SETJMP 1
|
||||
|
||||
@@ -111,6 +111,9 @@ typedef unsigned int uintptr_t;
|
||||
# define SDL_DISABLE_AVX 1
|
||||
#endif
|
||||
|
||||
#define HAVE_STDARG_H 1
|
||||
#define HAVE_STDDEF_H 1
|
||||
|
||||
/* This can be disabled to avoid C runtime dependencies and manifest requirements */
|
||||
#ifndef HAVE_LIBC
|
||||
#define HAVE_LIBC 1
|
||||
@@ -122,8 +125,6 @@ typedef unsigned int uintptr_t;
|
||||
#define HAVE_LIMITS_H 1
|
||||
#define HAVE_MATH_H 1
|
||||
#define HAVE_SIGNAL_H 1
|
||||
#define HAVE_STDARG_H 1
|
||||
#define HAVE_STDDEF_H 1
|
||||
#define HAVE_STDIO_H 1
|
||||
#define HAVE_STDLIB_H 1
|
||||
#define HAVE_STRING_H 1
|
||||
@@ -153,7 +154,6 @@ typedef unsigned int uintptr_t;
|
||||
#define HAVE_STRCMP 1
|
||||
#define HAVE_STRNCMP 1
|
||||
#define HAVE_STRPBRK 1
|
||||
#define HAVE_VSSCANF 1
|
||||
#define HAVE_VSNPRINTF 1
|
||||
#define HAVE_ACOS 1
|
||||
#define HAVE_ASIN 1
|
||||
@@ -211,10 +211,7 @@ typedef unsigned int uintptr_t;
|
||||
#if _MSC_VER >= 1400
|
||||
#define HAVE__FSEEKI64 1
|
||||
#endif
|
||||
#endif /* _MSC_VER */
|
||||
#else
|
||||
#define HAVE_STDARG_H 1
|
||||
#define HAVE_STDDEF_H 1
|
||||
#endif /* _MSC_VER */
|
||||
#endif
|
||||
|
||||
/* Enable various audio drivers */
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
// Initialization/Cleanup routines
|
||||
#include "timer/SDL_timer_c.h"
|
||||
#ifdef SDL_VIDEO_DRIVER_WINDOWS
|
||||
#ifdef SDL_PLATFORM_WINDOWS
|
||||
extern bool SDL_HelperWindowCreate(void);
|
||||
extern void SDL_HelperWindowDestroy(void);
|
||||
#endif
|
||||
@@ -317,7 +317,7 @@ bool SDL_InitSubSystem(SDL_InitFlags flags)
|
||||
SDL_DBus_Init();
|
||||
#endif
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_WINDOWS
|
||||
#ifdef SDL_PLATFORM_WINDOWS
|
||||
if (flags & (SDL_INIT_HAPTIC | SDL_INIT_JOYSTICK)) {
|
||||
if (!SDL_HelperWindowCreate()) {
|
||||
goto quit_and_error;
|
||||
@@ -653,7 +653,7 @@ void SDL_Quit(void)
|
||||
SDL_bInMainQuit = true;
|
||||
|
||||
// Quit all subsystems
|
||||
#ifdef SDL_VIDEO_DRIVER_WINDOWS
|
||||
#ifdef SDL_PLATFORM_WINDOWS
|
||||
SDL_HelperWindowDestroy();
|
||||
#endif
|
||||
SDL_QuitSubSystem(SDL_INIT_EVERYTHING);
|
||||
|
||||
+29
-9
@@ -1153,7 +1153,10 @@ bool SDL_PlaybackAudioThreadIterate(SDL_AudioDevice *device)
|
||||
// We should have updated this elsewhere if the format changed!
|
||||
SDL_assert(SDL_AudioSpecsEqual(&stream->dst_spec, &device->spec, NULL, NULL));
|
||||
|
||||
SDL_assert(stream->src_spec.format != SDL_AUDIO_UNKNOWN);
|
||||
|
||||
const int br = SDL_GetAtomicInt(&logdev->paused) ? 0 : SDL_GetAudioStreamDataAdjustGain(stream, device_buffer, buffer_size, logdev->gain);
|
||||
|
||||
if (br < 0) { // Probably OOM. Kill the audio device; the whole thing is likely dying soon anyhow.
|
||||
failed = true;
|
||||
SDL_memset(device_buffer, device->silence_value, buffer_size); // just supply silence to the device before we die.
|
||||
@@ -1195,6 +1198,8 @@ bool SDL_PlaybackAudioThreadIterate(SDL_AudioDevice *device)
|
||||
// We should have updated this elsewhere if the format changed!
|
||||
SDL_assert(SDL_AudioSpecsEqual(&stream->dst_spec, &outspec, NULL, NULL));
|
||||
|
||||
SDL_assert(stream->src_spec.format != SDL_AUDIO_UNKNOWN);
|
||||
|
||||
/* this will hold a lock on `stream` while getting. We don't explicitly lock the streams
|
||||
for iterating here because the binding linked list can only change while the device lock is held.
|
||||
(we _do_ lock the stream during binding/unbinding to make sure that two threads can't try to bind
|
||||
@@ -1330,6 +1335,7 @@ bool SDL_RecordingAudioThreadIterate(SDL_AudioDevice *device)
|
||||
SDL_assert(stream->src_spec.format == ((logdev->postmix || (logdev->gain != 1.0f)) ? SDL_AUDIO_F32 : device->spec.format));
|
||||
SDL_assert(stream->src_spec.channels == device->spec.channels);
|
||||
SDL_assert(stream->src_spec.freq == device->spec.freq);
|
||||
SDL_assert(stream->dst_spec.format != SDL_AUDIO_UNKNOWN);
|
||||
|
||||
void *final_buf = output_buffer;
|
||||
|
||||
@@ -1391,6 +1397,7 @@ static int SDLCALL RecordingAudioThread(void *devicep) // thread entry point
|
||||
typedef struct CountAudioDevicesData
|
||||
{
|
||||
int devs_seen;
|
||||
int devs_skipped;
|
||||
const int num_devices;
|
||||
SDL_AudioDeviceID *result;
|
||||
const bool recording;
|
||||
@@ -1406,7 +1413,13 @@ static bool SDLCALL CountAudioDevices(void *userdata, const SDL_HashTable *table
|
||||
const bool isphysical = !!(devid & (1<<1));
|
||||
if (isphysical && (devid_recording == data->recording)) {
|
||||
SDL_assert(data->devs_seen < data->num_devices);
|
||||
data->result[data->devs_seen++] = devid;
|
||||
SDL_AudioDevice *device = (SDL_AudioDevice *) value; // this is normally risky, but we hold the device_hash_lock here.
|
||||
const bool zombie = SDL_GetAtomicInt(&device->zombie) != 0;
|
||||
if (zombie) {
|
||||
data->devs_skipped++;
|
||||
} else {
|
||||
data->result[data->devs_seen++] = devid;
|
||||
}
|
||||
}
|
||||
return true; // keep iterating.
|
||||
}
|
||||
@@ -1422,10 +1435,11 @@ static SDL_AudioDeviceID *GetAudioDevices(int *count, bool recording)
|
||||
num_devices = SDL_GetAtomicInt(recording ? ¤t_audio.recording_device_count : ¤t_audio.playback_device_count);
|
||||
result = (SDL_AudioDeviceID *) SDL_malloc((num_devices + 1) * sizeof (SDL_AudioDeviceID));
|
||||
if (result) {
|
||||
CountAudioDevicesData data = { 0, num_devices, result, recording };
|
||||
CountAudioDevicesData data = { 0, 0, num_devices, result, recording };
|
||||
SDL_IterateHashTable(current_audio.device_hash, CountAudioDevices, &data);
|
||||
SDL_assert(data.devs_seen == num_devices);
|
||||
result[data.devs_seen] = 0; // null-terminated.
|
||||
SDL_assert((data.devs_seen + data.devs_skipped) == num_devices);
|
||||
num_devices = data.devs_seen; // might be less if we skipped any.
|
||||
result[num_devices] = 0; // null-terminated.
|
||||
}
|
||||
}
|
||||
SDL_UnlockRWLock(current_audio.device_hash_lock);
|
||||
@@ -1567,7 +1581,9 @@ int *SDL_GetAudioDeviceChannelMap(SDL_AudioDeviceID devid, int *count)
|
||||
SDL_AudioDevice *device = ObtainPhysicalAudioDeviceDefaultAllowed(devid);
|
||||
if (device) {
|
||||
channels = device->spec.channels;
|
||||
result = SDL_ChannelMapDup(device->chmap, channels);
|
||||
if (channels > 0 && device->chmap) {
|
||||
result = SDL_ChannelMapDup(device->chmap, channels);
|
||||
}
|
||||
}
|
||||
ReleaseAudioDevice(device);
|
||||
|
||||
@@ -1965,10 +1981,6 @@ bool SDL_BindAudioStreams(SDL_AudioDeviceID devid, SDL_AudioStream * const *stre
|
||||
} else if (logdev->simplified) {
|
||||
result = SDL_SetError("Cannot change stream bindings on device opened with SDL_OpenAudioDeviceStream");
|
||||
} else {
|
||||
|
||||
// !!! FIXME: We'll set the device's side's format below, but maybe we should refuse to bind a stream if the app's side doesn't have a format set yet.
|
||||
// !!! FIXME: Actually, why do we allow there to be an invalid format, again?
|
||||
|
||||
// make sure start of list is sane.
|
||||
SDL_assert(!logdev->bound_streams || (logdev->bound_streams->prev_binding == NULL));
|
||||
|
||||
@@ -2003,9 +2015,17 @@ bool SDL_BindAudioStreams(SDL_AudioDeviceID devid, SDL_AudioStream * const *stre
|
||||
|
||||
if (result) {
|
||||
// Now that everything is verified, chain everything together.
|
||||
const bool recording = device->recording;
|
||||
for (int i = 0; i < num_streams; i++) {
|
||||
SDL_AudioStream *stream = streams[i];
|
||||
if (stream) { // shouldn't be NULL, but just in case...
|
||||
// if the stream never had its non-device-end format set, just set it to the device end's format.
|
||||
if (recording && (stream->dst_spec.format == SDL_AUDIO_UNKNOWN)) {
|
||||
SDL_copyp(&stream->dst_spec, &device->spec);
|
||||
} else if (!recording && (stream->src_spec.format == SDL_AUDIO_UNKNOWN)) {
|
||||
SDL_copyp(&stream->src_spec, &device->spec);
|
||||
}
|
||||
|
||||
stream->bound_device = logdev;
|
||||
stream->prev_binding = NULL;
|
||||
stream->next_binding = logdev->bound_streams;
|
||||
|
||||
@@ -537,8 +537,10 @@ static void SDL_TARGETING("ssse3") SDL_Convert_Swap32_SSSE3(Uint32* dst, const U
|
||||
// behavior. However, the compiler support for this pragma is bad.
|
||||
#if defined(__clang__)
|
||||
#if __clang_major__ >= 12
|
||||
#if defined(__aarch64__)
|
||||
#pragma STDC FENV_ACCESS ON
|
||||
#endif
|
||||
#endif
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma fenv_access (on)
|
||||
#elif defined(__GNUC__)
|
||||
@@ -814,8 +816,10 @@ static void SDL_Convert_Swap32_NEON(Uint32* dst, const Uint32* src, int num_samp
|
||||
|
||||
#if defined(__clang__)
|
||||
#if __clang_major__ >= 12
|
||||
#if defined(__aarch64__)
|
||||
#pragma STDC FENV_ACCESS DEFAULT
|
||||
#endif
|
||||
#endif
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma fenv_access (off)
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
+11
-2
@@ -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.
|
||||
*/
|
||||
@@ -2114,8 +2123,8 @@ bool SDL_LoadWAV_IO(SDL_IOStream *src, bool closeio, SDL_AudioSpec *spec, Uint8
|
||||
result = WaveLoad(src, &file, spec, audio_buf, audio_len);
|
||||
if (!result) {
|
||||
SDL_free(*audio_buf);
|
||||
audio_buf = NULL;
|
||||
audio_len = 0;
|
||||
*audio_buf = NULL;
|
||||
*audio_len = 0;
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
|
||||
@@ -1156,7 +1156,7 @@ static bool ALSA_OpenDevice(SDL_AudioDevice *device)
|
||||
#if SDL_ALSA_DEBUG
|
||||
snd_pcm_uframes_t bufsize;
|
||||
ALSA_snd_pcm_hw_params_get_buffer_size(cfg_ctx.hwparams, &bufsize);
|
||||
SDL_LogError(SDL_LOG_CATEGORY_AUDIO,
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_AUDIO,
|
||||
"ALSA: period size = %ld, periods = %u, buffer size = %lu",
|
||||
cfg_ctx.persize, cfg_ctx.periods, bufsize);
|
||||
#endif
|
||||
|
||||
@@ -420,7 +420,8 @@ static bool UpdateAudioSession(SDL_AudioDevice *device, bool open, bool allow_pl
|
||||
|
||||
hint = SDL_GetHint(SDL_HINT_AUDIO_CATEGORY);
|
||||
if (hint) {
|
||||
if (SDL_strcasecmp(hint, "AVAudioSessionCategoryAmbient") == 0) {
|
||||
if (SDL_strcasecmp(hint, "AVAudioSessionCategoryAmbient") == 0 ||
|
||||
SDL_strcasecmp(hint, "ambient") == 0) {
|
||||
category = AVAudioSessionCategoryAmbient;
|
||||
} else if (SDL_strcasecmp(hint, "AVAudioSessionCategorySoloAmbient") == 0) {
|
||||
category = AVAudioSessionCategorySoloAmbient;
|
||||
|
||||
@@ -206,7 +206,7 @@ static void DSOUND_DetectDevices(SDL_AudioDevice **default_playback, SDL_AudioDe
|
||||
{
|
||||
#ifdef HAVE_MMDEVICEAPI_H
|
||||
if (SupportsIMMDevice) {
|
||||
SDL_IMMDevice_EnumerateEndpoints(default_playback, default_recording);
|
||||
SDL_IMMDevice_EnumerateEndpoints(default_playback, default_recording, SDL_AUDIO_UNKNOWN);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
||||
@@ -426,28 +426,33 @@ static void OPENSLES_DestroyPCMPlayer(SDL_AudioDevice *device)
|
||||
|
||||
static bool OPENSLES_CreatePCMPlayer(SDL_AudioDevice *device)
|
||||
{
|
||||
/* If we want to add floating point audio support (requires API level 21)
|
||||
it can be done as described here:
|
||||
https://developer.android.com/ndk/guides/audio/opensl/android-extensions.html#floating-point
|
||||
*/
|
||||
/* according to https://developer.android.com/ndk/guides/audio/opensl/opensl-for-android,
|
||||
Android's OpenSL ES only supports Uint8 and _littleendian_ Sint16.
|
||||
(and float32, with an extension we use, below.) */
|
||||
if (SDL_GetAndroidSDKVersion() >= 21) {
|
||||
const SDL_AudioFormat *closefmts = SDL_ClosestAudioFormats(device->spec.format);
|
||||
SDL_AudioFormat test_format;
|
||||
while ((test_format = *(closefmts++)) != 0) {
|
||||
if (SDL_AUDIO_ISSIGNED(test_format)) {
|
||||
switch (test_format) {
|
||||
case SDL_AUDIO_U8:
|
||||
case SDL_AUDIO_S16LE:
|
||||
case SDL_AUDIO_F32:
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!test_format) {
|
||||
// Didn't find a compatible format :
|
||||
LOGI("No compatible audio format, using signed 16-bit audio");
|
||||
test_format = SDL_AUDIO_S16;
|
||||
LOGI("No compatible audio format, using signed 16-bit LE audio");
|
||||
test_format = SDL_AUDIO_S16LE;
|
||||
}
|
||||
device->spec.format = test_format;
|
||||
} else {
|
||||
// Just go with signed 16-bit audio as it's the most compatible
|
||||
device->spec.format = SDL_AUDIO_S16;
|
||||
device->spec.format = SDL_AUDIO_S16LE;
|
||||
}
|
||||
|
||||
// Update the fragment size as size in bytes
|
||||
|
||||
@@ -114,7 +114,7 @@ static bool PSPAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, in
|
||||
} else {
|
||||
rc = sceAudioOutputPannedBlocking(device->hidden->channel, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, (void *) buffer);
|
||||
}
|
||||
return (rc == 0);
|
||||
return (rc >= 0);
|
||||
}
|
||||
|
||||
static bool PSPAUDIO_WaitDevice(SDL_AudioDevice *device)
|
||||
|
||||
@@ -337,7 +337,7 @@ typedef struct
|
||||
static bool mgmtthrtask_DetectDevices(void *userdata)
|
||||
{
|
||||
mgmtthrtask_DetectDevicesData *data = (mgmtthrtask_DetectDevicesData *)userdata;
|
||||
SDL_IMMDevice_EnumerateEndpoints(data->default_playback, data->default_recording);
|
||||
SDL_IMMDevice_EnumerateEndpoints(data->default_playback, data->default_recording, SDL_AUDIO_F32);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -814,7 +814,7 @@ static void ANDROIDCAMERA_Deinitialize(void)
|
||||
static bool ANDROIDCAMERA_Init(SDL_CameraDriverImpl *impl)
|
||||
{
|
||||
// !!! FIXME: slide this off into a subroutine
|
||||
// system libraries are in android-24 and later; we currently target android-16 and later, so check if they exist at runtime.
|
||||
// system libraries are in android-24 and later; we currently target android-21 and later, so check if they exist at runtime.
|
||||
void *libcamera2 = dlopen("libcamera2ndk.so", RTLD_NOW | RTLD_LOCAL);
|
||||
if (!libcamera2) {
|
||||
SDL_Log("CAMERA: libcamera2ndk.so can't be loaded: %s", dlerror());
|
||||
|
||||
@@ -1080,7 +1080,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeAddTouch)(
|
||||
{
|
||||
const char *utfname = (*env)->GetStringUTFChars(env, name, NULL);
|
||||
|
||||
SDL_AddTouch((SDL_TouchID)touchId, SDL_TOUCH_DEVICE_DIRECT, utfname);
|
||||
SDL_AddTouch(Android_ConvertJavaTouchID(touchId),
|
||||
SDL_TOUCH_DEVICE_DIRECT, utfname);
|
||||
|
||||
(*env)->ReleaseStringUTFChars(env, name, utfname);
|
||||
}
|
||||
@@ -1728,18 +1729,24 @@ static bool Android_JNI_ExceptionOccurred(bool silent)
|
||||
exceptionName = (jstring)(*env)->CallObjectMethod(env, exceptionClass, mid);
|
||||
exceptionNameUTF8 = (*env)->GetStringUTFChars(env, exceptionName, 0);
|
||||
|
||||
(*env)->DeleteLocalRef(env, classClass);
|
||||
|
||||
mid = (*env)->GetMethodID(env, exceptionClass, "getMessage", "()Ljava/lang/String;");
|
||||
exceptionMessage = (jstring)(*env)->CallObjectMethod(env, exception, mid);
|
||||
|
||||
(*env)->DeleteLocalRef(env, exceptionClass);
|
||||
|
||||
if (exceptionMessage != NULL) {
|
||||
const char *exceptionMessageUTF8 = (*env)->GetStringUTFChars(env, exceptionMessage, 0);
|
||||
SDL_SetError("%s: %s", exceptionNameUTF8, exceptionMessageUTF8);
|
||||
(*env)->ReleaseStringUTFChars(env, exceptionMessage, exceptionMessageUTF8);
|
||||
(*env)->DeleteLocalRef(env, exceptionMessage);
|
||||
} else {
|
||||
SDL_SetError("%s", exceptionNameUTF8);
|
||||
}
|
||||
|
||||
(*env)->ReleaseStringUTFChars(env, exceptionName, exceptionNameUTF8);
|
||||
(*env)->DeleteLocalRef(env, exceptionName);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -2163,7 +2170,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,
|
||||
@@ -2417,7 +2424,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);
|
||||
@@ -2767,6 +2774,7 @@ bool Android_JNI_OpenFileDialog(
|
||||
if (filters) {
|
||||
jclass stringClass = (*env)->FindClass(env, "java/lang/String");
|
||||
filtersArray = (*env)->NewObjectArray(env, nfilters, stringClass, NULL);
|
||||
(*env)->DeleteLocalRef(env, stringClass);
|
||||
|
||||
// Convert to string
|
||||
for (int i = 0; i < nfilters; i++) {
|
||||
|
||||
@@ -105,7 +105,7 @@ bool GDK_RegisterChangeNotifications(void)
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "[GDK] in RegisterAppConstrainedChangeNotification handler");
|
||||
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
||||
if (_this) {
|
||||
if (constrained) {
|
||||
if (constrained && !((_this->windows) && _this->windows->text_input_active)) {
|
||||
SDL_SetKeyboardFocus(NULL);
|
||||
} else {
|
||||
SDL_SetKeyboardFocus(_this->windows);
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "SDL_fcitx.h"
|
||||
#include "../../video/SDL_sysvideo.h"
|
||||
#include "../../events/SDL_keyboard_c.h"
|
||||
#include "../../core/unix/SDL_appid.h"
|
||||
#include "SDL_dbus.h"
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_X11
|
||||
@@ -53,32 +54,14 @@ typedef struct FcitxClient
|
||||
|
||||
static FcitxClient fcitx_client;
|
||||
|
||||
static char *GetAppName(void)
|
||||
static const char *GetAppName(void)
|
||||
{
|
||||
#if defined(SDL_PLATFORM_LINUX) || defined(SDL_PLATFORM_FREEBSD)
|
||||
char *spot;
|
||||
char procfile[1024];
|
||||
char linkfile[1024];
|
||||
int linksize;
|
||||
|
||||
#ifdef SDL_PLATFORM_LINUX
|
||||
(void)SDL_snprintf(procfile, sizeof(procfile), "/proc/%d/exe", getpid());
|
||||
#elif defined(SDL_PLATFORM_FREEBSD)
|
||||
(void)SDL_snprintf(procfile, sizeof(procfile), "/proc/%d/file", getpid());
|
||||
#endif
|
||||
linksize = readlink(procfile, linkfile, sizeof(linkfile) - 1);
|
||||
if (linksize > 0) {
|
||||
linkfile[linksize] = '\0';
|
||||
spot = SDL_strrchr(linkfile, '/');
|
||||
if (spot) {
|
||||
return SDL_strdup(spot + 1);
|
||||
} else {
|
||||
return SDL_strdup(linkfile);
|
||||
}
|
||||
const char *exe_name = SDL_GetExeName();
|
||||
if (exe_name) {
|
||||
return exe_name;
|
||||
}
|
||||
#endif // SDL_PLATFORM_LINUX || SDL_PLATFORM_FREEBSD
|
||||
|
||||
return SDL_strdup("SDL_App");
|
||||
return "SDL_App";
|
||||
}
|
||||
|
||||
static size_t Fcitx_GetPreeditString(SDL_DBusContext *dbus,
|
||||
@@ -281,7 +264,7 @@ static bool FcitxCreateInputContext(SDL_DBusContext *dbus, const char *appname,
|
||||
|
||||
static bool FcitxClientCreateIC(FcitxClient *client)
|
||||
{
|
||||
char *appname = GetAppName();
|
||||
const char *appname = GetAppName();
|
||||
char *ic_path = NULL;
|
||||
SDL_DBusContext *dbus = client->dbus;
|
||||
|
||||
@@ -290,8 +273,6 @@ static bool FcitxClientCreateIC(FcitxClient *client)
|
||||
ic_path = NULL; // just in case.
|
||||
}
|
||||
|
||||
SDL_free(appname);
|
||||
|
||||
if (ic_path) {
|
||||
SDL_free(client->ic_path);
|
||||
client->ic_path = SDL_strdup(ic_path);
|
||||
|
||||
@@ -120,7 +120,7 @@ void SDL_IMMDevice_FreeDeviceHandle(SDL_AudioDevice *device)
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_AudioDevice *SDL_IMMDevice_Add(const bool recording, const char *devname, WAVEFORMATEXTENSIBLE *fmt, LPCWSTR devid, GUID *dsoundguid)
|
||||
static SDL_AudioDevice *SDL_IMMDevice_Add(const bool recording, const char *devname, WAVEFORMATEXTENSIBLE *fmt, LPCWSTR devid, GUID *dsoundguid, SDL_AudioFormat force_format)
|
||||
{
|
||||
/* You can have multiple endpoints on a device that are mutually exclusive ("Speakers" vs "Line Out" or whatever).
|
||||
In a perfect world, things that are unplugged won't be in this collection. The only gotcha is probably for
|
||||
@@ -162,7 +162,7 @@ static SDL_AudioDevice *SDL_IMMDevice_Add(const bool recording, const char *devn
|
||||
SDL_zero(spec);
|
||||
spec.channels = (Uint8)fmt->Format.nChannels;
|
||||
spec.freq = fmt->Format.nSamplesPerSec;
|
||||
spec.format = SDL_WaveFormatExToSDLFormat((WAVEFORMATEX *)fmt);
|
||||
spec.format = (force_format != SDL_AUDIO_UNKNOWN) ? force_format : SDL_WaveFormatExToSDLFormat((WAVEFORMATEX *)fmt);
|
||||
|
||||
device = SDL_AddAudioDevice(recording, devname, &spec, handle);
|
||||
if (!device) {
|
||||
@@ -183,6 +183,7 @@ typedef struct SDLMMNotificationClient
|
||||
{
|
||||
const IMMNotificationClientVtbl *lpVtbl;
|
||||
SDL_AtomicInt refcount;
|
||||
SDL_AudioFormat force_format;
|
||||
} SDLMMNotificationClient;
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_QueryInterface(IMMNotificationClient *client, REFIID iid, void **ppv)
|
||||
@@ -241,6 +242,7 @@ static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnDeviceRemoved(IMMNoti
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnDeviceStateChanged(IMMNotificationClient *iclient, LPCWSTR pwstrDeviceId, DWORD dwNewState)
|
||||
{
|
||||
SDLMMNotificationClient *client = (SDLMMNotificationClient *)iclient;
|
||||
IMMDevice *device = NULL;
|
||||
|
||||
if (SUCCEEDED(IMMDeviceEnumerator_GetDevice(enumerator, pwstrDeviceId, &device))) {
|
||||
@@ -255,7 +257,7 @@ static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnDeviceStateChanged(IM
|
||||
GUID dsoundguid;
|
||||
GetMMDeviceInfo(device, &utf8dev, &fmt, &dsoundguid);
|
||||
if (utf8dev) {
|
||||
SDL_IMMDevice_Add(recording, utf8dev, &fmt, pwstrDeviceId, &dsoundguid);
|
||||
SDL_IMMDevice_Add(recording, utf8dev, &fmt, pwstrDeviceId, &dsoundguid, client->force_format);
|
||||
SDL_free(utf8dev);
|
||||
}
|
||||
} else {
|
||||
@@ -286,7 +288,7 @@ static const IMMNotificationClientVtbl notification_client_vtbl = {
|
||||
SDLMMNotificationClient_OnPropertyValueChanged
|
||||
};
|
||||
|
||||
static SDLMMNotificationClient notification_client = { ¬ification_client_vtbl, { 1 } };
|
||||
static SDLMMNotificationClient notification_client = { ¬ification_client_vtbl, { 1 }, SDL_AUDIO_UNKNOWN };
|
||||
|
||||
bool SDL_IMMDevice_Init(const SDL_IMMDevice_callbacks *callbacks)
|
||||
{
|
||||
@@ -363,7 +365,7 @@ bool SDL_IMMDevice_Get(SDL_AudioDevice *device, IMMDevice **immdevice, bool reco
|
||||
return true;
|
||||
}
|
||||
|
||||
static void EnumerateEndpointsForFlow(const bool recording, SDL_AudioDevice **default_device)
|
||||
static void EnumerateEndpointsForFlow(const bool recording, SDL_AudioDevice **default_device, SDL_AudioFormat force_format)
|
||||
{
|
||||
/* Note that WASAPI separates "adapter devices" from "audio endpoint devices"
|
||||
...one adapter device ("SoundBlaster Pro") might have multiple endpoint devices ("Speakers", "Line-Out"). */
|
||||
@@ -405,7 +407,7 @@ static void EnumerateEndpointsForFlow(const bool recording, SDL_AudioDevice **de
|
||||
SDL_zero(dsoundguid);
|
||||
GetMMDeviceInfo(immdevice, &devname, &fmt, &dsoundguid);
|
||||
if (devname) {
|
||||
SDL_AudioDevice *sdldevice = SDL_IMMDevice_Add(recording, devname, &fmt, devid, &dsoundguid);
|
||||
SDL_AudioDevice *sdldevice = SDL_IMMDevice_Add(recording, devname, &fmt, devid, &dsoundguid, force_format);
|
||||
if (default_device && default_devid && SDL_wcscmp(default_devid, devid) == 0) {
|
||||
*default_device = sdldevice;
|
||||
}
|
||||
@@ -422,10 +424,12 @@ static void EnumerateEndpointsForFlow(const bool recording, SDL_AudioDevice **de
|
||||
IMMDeviceCollection_Release(collection);
|
||||
}
|
||||
|
||||
void SDL_IMMDevice_EnumerateEndpoints(SDL_AudioDevice **default_playback, SDL_AudioDevice **default_recording)
|
||||
void SDL_IMMDevice_EnumerateEndpoints(SDL_AudioDevice **default_playback, SDL_AudioDevice **default_recording, SDL_AudioFormat force_format)
|
||||
{
|
||||
EnumerateEndpointsForFlow(false, default_playback);
|
||||
EnumerateEndpointsForFlow(true, default_recording);
|
||||
EnumerateEndpointsForFlow(false, default_playback, force_format);
|
||||
EnumerateEndpointsForFlow(true, default_recording, force_format);
|
||||
|
||||
notification_client.force_format = force_format;
|
||||
|
||||
// if this fails, we just won't get hotplug events. Carry on anyhow.
|
||||
IMMDeviceEnumerator_RegisterEndpointNotificationCallback(enumerator, (IMMNotificationClient *)¬ification_client);
|
||||
|
||||
@@ -37,7 +37,7 @@ typedef struct SDL_IMMDevice_callbacks
|
||||
bool SDL_IMMDevice_Init(const SDL_IMMDevice_callbacks *callbacks);
|
||||
void SDL_IMMDevice_Quit(void);
|
||||
bool SDL_IMMDevice_Get(struct SDL_AudioDevice *device, IMMDevice **immdevice, bool recording);
|
||||
void SDL_IMMDevice_EnumerateEndpoints(struct SDL_AudioDevice **default_playback, struct SDL_AudioDevice **default_recording);
|
||||
void SDL_IMMDevice_EnumerateEndpoints(struct SDL_AudioDevice **default_playback, struct SDL_AudioDevice **default_recording, SDL_AudioFormat force_format);
|
||||
LPGUID SDL_IMMDevice_GetDirectSoundGUID(struct SDL_AudioDevice *device);
|
||||
LPCWSTR SDL_IMMDevice_GetDevID(struct SDL_AudioDevice *device);
|
||||
void SDL_IMMDevice_FreeDeviceHandle(struct SDL_AudioDevice *device);
|
||||
|
||||
@@ -53,6 +53,78 @@ typedef enum RO_INIT_TYPE
|
||||
#define WC_ERR_INVALID_CHARS 0x00000080
|
||||
#endif
|
||||
|
||||
// Fake window to help with DirectInput events.
|
||||
HWND SDL_HelperWindow = NULL;
|
||||
static const TCHAR *SDL_HelperWindowClassName = TEXT("SDLHelperWindowInputCatcher");
|
||||
static const TCHAR *SDL_HelperWindowName = TEXT("SDLHelperWindowInputMsgWindow");
|
||||
static ATOM SDL_HelperWindowClass = 0;
|
||||
|
||||
/*
|
||||
* Creates a HelperWindow used for DirectInput.
|
||||
*/
|
||||
bool SDL_HelperWindowCreate(void)
|
||||
{
|
||||
HINSTANCE hInstance = GetModuleHandle(NULL);
|
||||
WNDCLASS wce;
|
||||
|
||||
// Make sure window isn't created twice.
|
||||
if (SDL_HelperWindow != NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Create the class.
|
||||
SDL_zero(wce);
|
||||
wce.lpfnWndProc = DefWindowProc;
|
||||
wce.lpszClassName = SDL_HelperWindowClassName;
|
||||
wce.hInstance = hInstance;
|
||||
|
||||
// Register the class.
|
||||
SDL_HelperWindowClass = RegisterClass(&wce);
|
||||
if (SDL_HelperWindowClass == 0 && GetLastError() != ERROR_CLASS_ALREADY_EXISTS) {
|
||||
return WIN_SetError("Unable to create Helper Window Class");
|
||||
}
|
||||
|
||||
// Create the window.
|
||||
SDL_HelperWindow = CreateWindowEx(0, SDL_HelperWindowClassName,
|
||||
SDL_HelperWindowName,
|
||||
WS_OVERLAPPED, CW_USEDEFAULT,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
CW_USEDEFAULT, HWND_MESSAGE, NULL,
|
||||
hInstance, NULL);
|
||||
if (!SDL_HelperWindow) {
|
||||
UnregisterClass(SDL_HelperWindowClassName, hInstance);
|
||||
return WIN_SetError("Unable to create Helper Window");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroys the HelperWindow previously created with SDL_HelperWindowCreate.
|
||||
*/
|
||||
void SDL_HelperWindowDestroy(void)
|
||||
{
|
||||
HINSTANCE hInstance = GetModuleHandle(NULL);
|
||||
|
||||
// Destroy the window.
|
||||
if (SDL_HelperWindow != NULL) {
|
||||
if (DestroyWindow(SDL_HelperWindow) == 0) {
|
||||
WIN_SetError("Unable to destroy Helper Window");
|
||||
return;
|
||||
}
|
||||
SDL_HelperWindow = NULL;
|
||||
}
|
||||
|
||||
// Unregister the class.
|
||||
if (SDL_HelperWindowClass != 0) {
|
||||
if ((UnregisterClass(SDL_HelperWindowClassName, hInstance)) == 0) {
|
||||
WIN_SetError("Unable to destroy Helper Window Class");
|
||||
return;
|
||||
}
|
||||
SDL_HelperWindowClass = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Sets an error message based on an HRESULT
|
||||
bool WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr)
|
||||
{
|
||||
|
||||
@@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,2,16,0
|
||||
PRODUCTVERSION 3,2,16,0
|
||||
FILEVERSION 3,2,26,0
|
||||
PRODUCTVERSION 3,2,26,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
FILEFLAGS 0x0L
|
||||
FILEOS 0x40004L
|
||||
@@ -23,12 +23,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "\0"
|
||||
VALUE "FileDescription", "SDL\0"
|
||||
VALUE "FileVersion", "3, 2, 16, 0\0"
|
||||
VALUE "FileVersion", "3, 2, 26, 0\0"
|
||||
VALUE "InternalName", "SDL\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2025 Sam Lantinga\0"
|
||||
VALUE "OriginalFilename", "SDL3.dll\0"
|
||||
VALUE "ProductName", "Simple DirectMedia Layer\0"
|
||||
VALUE "ProductVersion", "3, 2, 16, 0\0"
|
||||
VALUE "ProductVersion", "3, 2, 26, 0\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <UniformTypeIdentifiers/UTType.h>
|
||||
|
||||
extern void Cocoa_SetWindowHasModalDialog(SDL_Window *window, bool has_modal);
|
||||
|
||||
static void AddFileExtensionType(NSMutableArray *types, const char *pattern_ptr)
|
||||
{
|
||||
if (!*pattern_ptr) {
|
||||
@@ -163,6 +165,9 @@ void SDL_SYS_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFil
|
||||
|
||||
if (window) {
|
||||
w = (__bridge NSWindow *)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, NULL);
|
||||
if (w) {
|
||||
Cocoa_SetWindowHasModalDialog(window, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (w) {
|
||||
@@ -186,6 +191,7 @@ void SDL_SYS_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFil
|
||||
callback(userdata, files, -1);
|
||||
}
|
||||
|
||||
Cocoa_SetWindowHasModalDialog(window, false);
|
||||
ReactivateAfterDialog();
|
||||
}];
|
||||
} else {
|
||||
@@ -206,6 +212,7 @@ void SDL_SYS_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFil
|
||||
const char *files[1] = { NULL };
|
||||
callback(userdata, files, -1);
|
||||
}
|
||||
|
||||
ReactivateAfterDialog();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1646,6 +1646,8 @@ bool SDL_WaitEventTimeoutNS(SDL_Event *event, Sint64 timeoutNS)
|
||||
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
for (;;) {
|
||||
SDL_PumpEventsInternal(true);
|
||||
|
||||
if (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_EVENT_FIRST, SDL_EVENT_LAST) > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+12
-12
@@ -333,6 +333,18 @@ bool SDL_SetKeyboardFocus(SDL_Window *window)
|
||||
}
|
||||
}
|
||||
|
||||
// See if the current window has lost focus
|
||||
if (keyboard->focus && keyboard->focus != window) {
|
||||
SDL_SendWindowEvent(keyboard->focus, SDL_EVENT_WINDOW_FOCUS_LOST, 0, 0);
|
||||
|
||||
// Ensures IME compositions are committed
|
||||
if (SDL_TextInputActive(keyboard->focus)) {
|
||||
if (video && video->StopTextInput) {
|
||||
video->StopTextInput(video, keyboard->focus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (keyboard->focus && !window) {
|
||||
// We won't get anymore keyboard messages, so reset keyboard state
|
||||
SDL_ResetKeyboard();
|
||||
@@ -351,18 +363,6 @@ bool SDL_SetKeyboardFocus(SDL_Window *window)
|
||||
}
|
||||
}
|
||||
|
||||
// See if the current window has lost focus
|
||||
if (keyboard->focus && keyboard->focus != window) {
|
||||
SDL_SendWindowEvent(keyboard->focus, SDL_EVENT_WINDOW_FOCUS_LOST, 0, 0);
|
||||
|
||||
// Ensures IME compositions are committed
|
||||
if (SDL_TextInputActive(keyboard->focus)) {
|
||||
if (video && video->StopTextInput) {
|
||||
video->StopTextInput(video, keyboard->focus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
keyboard->focus = window;
|
||||
|
||||
if (keyboard->focus) {
|
||||
|
||||
@@ -77,9 +77,6 @@ bool SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent, int data
|
||||
}
|
||||
SDL_assert(SDL_ObjectValid(window, SDL_OBJECT_TYPE_WINDOW));
|
||||
|
||||
if (window->is_destroying && windowevent != SDL_EVENT_WINDOW_DESTROYED) {
|
||||
return false;
|
||||
}
|
||||
switch (windowevent) {
|
||||
case SDL_EVENT_WINDOW_SHOWN:
|
||||
if (!(window->flags & SDL_WINDOW_HIDDEN)) {
|
||||
@@ -212,6 +209,10 @@ bool SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent, int data
|
||||
break;
|
||||
}
|
||||
|
||||
if (window->is_destroying && windowevent != SDL_EVENT_WINDOW_DESTROYED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Post the event, if desired
|
||||
SDL_Event event;
|
||||
event.type = windowevent;
|
||||
|
||||
@@ -371,10 +371,10 @@ static const SDL_Scancode xfree86_scancode_table2[] = {
|
||||
/* 188, 0x0bc */ SDL_SCANCODE_F18, // XF86Launch9
|
||||
/* 189, 0x0bd */ SDL_SCANCODE_F19, // NoSymbol
|
||||
/* 190, 0x0be */ SDL_SCANCODE_F20, // XF86AudioMicMute
|
||||
/* 191, 0x0bf */ SDL_SCANCODE_UNKNOWN, // XF86TouchpadToggle
|
||||
/* 192, 0x0c0 */ SDL_SCANCODE_UNKNOWN, // XF86TouchpadOn
|
||||
/* 193, 0x0c1 */ SDL_SCANCODE_UNKNOWN, // XF86TouchpadOff
|
||||
/* 194, 0x0c2 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
|
||||
/* 191, 0x0bf */ SDL_SCANCODE_F21, // XF86TouchpadToggle
|
||||
/* 192, 0x0c0 */ SDL_SCANCODE_F22, // XF86TouchpadOn
|
||||
/* 193, 0x0c1 */ SDL_SCANCODE_F23, // XF86TouchpadOff
|
||||
/* 194, 0x0c2 */ SDL_SCANCODE_F24, // NoSymbol
|
||||
/* 195, 0x0c3 */ SDL_SCANCODE_MODE, // Mode_switch
|
||||
/* 196, 0x0c4 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
|
||||
/* 197, 0x0c5 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
|
||||
|
||||
@@ -78,7 +78,7 @@ static char *search_path_for_binary(const char *bin)
|
||||
char *envr;
|
||||
size_t alloc_size;
|
||||
char *exe = NULL;
|
||||
char *start = envr;
|
||||
char *start;
|
||||
char *ptr;
|
||||
|
||||
if (!envr_real) {
|
||||
@@ -86,7 +86,7 @@ static char *search_path_for_binary(const char *bin)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
envr = SDL_strdup(envr_real);
|
||||
start = envr = SDL_strdup(envr_real);
|
||||
if (!envr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+21
-4
@@ -61,6 +61,10 @@
|
||||
return; \
|
||||
}
|
||||
|
||||
#if 0
|
||||
// The below validation is too aggressive, since there are advanced situations
|
||||
// where this is legal. This is being temporarily disabled for further review.
|
||||
// See: https://github.com/libsdl-org/SDL/issues/13871
|
||||
#define CHECK_SAMPLER_TEXTURES \
|
||||
RenderPass *rp = (RenderPass *)render_pass; \
|
||||
for (Uint32 color_target_index = 0; color_target_index < rp->num_color_targets; color_target_index += 1) { \
|
||||
@@ -92,6 +96,10 @@
|
||||
SDL_assert_release(!"Texture cannot be simultaneously bound as a depth stencil target and a storage texture!"); \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define CHECK_SAMPLER_TEXTURES
|
||||
#define CHECK_STORAGE_TEXTURES
|
||||
#endif
|
||||
|
||||
#define CHECK_GRAPHICS_PIPELINE_BOUND \
|
||||
if (!((RenderPass *)render_pass)->graphics_pipeline) { \
|
||||
@@ -1312,6 +1320,12 @@ SDL_GPUBuffer *SDL_CreateGPUBuffer(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (device->debug_mode) {
|
||||
if (createinfo->size < 4) {
|
||||
SDL_assert_release(!"Cannot create a buffer with size less than 4 bytes!");
|
||||
}
|
||||
}
|
||||
|
||||
const char *debugName = SDL_GetStringProperty(createinfo->props, SDL_PROP_GPU_BUFFER_CREATE_NAME_STRING, NULL);
|
||||
|
||||
return device->CreateBuffer(
|
||||
@@ -1573,6 +1587,7 @@ SDL_GPUCommandBuffer *SDL_AcquireGPUCommandBuffer(
|
||||
commandBufferHeader->copy_pass.in_progress = false;
|
||||
commandBufferHeader->swapchain_texture_acquired = false;
|
||||
commandBufferHeader->submitted = false;
|
||||
commandBufferHeader->ignore_render_pass_texture_validation = false;
|
||||
SDL_zeroa(commandBufferHeader->render_pass.vertex_sampler_bound);
|
||||
SDL_zeroa(commandBufferHeader->render_pass.vertex_storage_texture_bound);
|
||||
SDL_zeroa(commandBufferHeader->render_pass.vertex_storage_buffer_bound);
|
||||
@@ -1784,6 +1799,8 @@ SDL_GPURenderPass *SDL_BeginGPURenderPass(
|
||||
commandBufferHeader->render_pass.num_color_targets = num_color_targets;
|
||||
if (depth_stencil_target_info != NULL) {
|
||||
commandBufferHeader->render_pass.depth_stencil_target = depth_stencil_target_info->texture;
|
||||
} else {
|
||||
commandBufferHeader->render_pass.depth_stencil_target = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2247,14 +2264,14 @@ void SDL_DrawGPUIndexedPrimitivesIndirect(
|
||||
void SDL_EndGPURenderPass(
|
||||
SDL_GPURenderPass *render_pass)
|
||||
{
|
||||
CommandBufferCommonHeader *commandBufferCommonHeader;
|
||||
commandBufferCommonHeader = (CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER;
|
||||
|
||||
if (render_pass == NULL) {
|
||||
SDL_InvalidParamError("render_pass");
|
||||
return;
|
||||
}
|
||||
|
||||
CommandBufferCommonHeader *commandBufferCommonHeader;
|
||||
commandBufferCommonHeader = (CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER;
|
||||
|
||||
if (RENDERPASS_DEVICE->debug_mode) {
|
||||
CHECK_RENDERPASS
|
||||
}
|
||||
@@ -2543,7 +2560,7 @@ void SDL_EndGPUComputePass(
|
||||
if (COMPUTEPASS_DEVICE->debug_mode) {
|
||||
commandBufferCommonHeader = (CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER;
|
||||
commandBufferCommonHeader->compute_pass.in_progress = false;
|
||||
commandBufferCommonHeader->compute_pass.compute_pipeline = false;
|
||||
commandBufferCommonHeader->compute_pass.compute_pipeline = NULL;
|
||||
SDL_zeroa(commandBufferCommonHeader->compute_pass.sampler_bound);
|
||||
SDL_zeroa(commandBufferCommonHeader->compute_pass.read_only_storage_texture_bound);
|
||||
SDL_zeroa(commandBufferCommonHeader->compute_pass.read_only_storage_buffer_bound);
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#define UNIFORM_BUFFER_SIZE 32768
|
||||
#define MAX_VERTEX_BUFFERS 16
|
||||
#define MAX_VERTEX_ATTRIBUTES 16
|
||||
#define MAX_COLOR_TARGET_BINDINGS 4
|
||||
#define MAX_COLOR_TARGET_BINDINGS 8
|
||||
#define MAX_PRESENT_COUNT 16
|
||||
#define MAX_FRAMES_IN_FLIGHT 3
|
||||
|
||||
|
||||
@@ -109,8 +109,8 @@
|
||||
#define DXGI_GET_DEBUG_INTERFACE_FUNC "DXGIGetDebugInterface"
|
||||
#define D3D12_GET_DEBUG_INTERFACE_FUNC "D3D12GetDebugInterface"
|
||||
#define WINDOW_PROPERTY_DATA "SDL_GPUD3D12WindowPropertyData"
|
||||
#define D3D_FEATURE_LEVEL_CHOICE D3D_FEATURE_LEVEL_11_1
|
||||
#define D3D_FEATURE_LEVEL_CHOICE_STR "11_1"
|
||||
#define D3D_FEATURE_LEVEL_CHOICE D3D_FEATURE_LEVEL_11_0
|
||||
#define D3D_FEATURE_LEVEL_CHOICE_STR "11_0"
|
||||
#define MAX_ROOT_SIGNATURE_PARAMETERS 64
|
||||
#define D3D12_FENCE_UNSIGNALED_VALUE 0
|
||||
#define D3D12_FENCE_SIGNAL_VALUE 1
|
||||
@@ -991,6 +991,10 @@ struct D3D12CommandBuffer
|
||||
// Set at acquire time
|
||||
D3D12DescriptorHeap *gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER + 1];
|
||||
|
||||
D3D12DescriptorHeap **usedDescriptorHeaps;
|
||||
Uint32 usedDescriptorHeapCount;
|
||||
Uint32 usedDescriptorHeapCapacity;
|
||||
|
||||
D3D12UniformBuffer **usedUniformBuffers;
|
||||
Uint32 usedUniformBufferCount;
|
||||
Uint32 usedUniformBufferCapacity;
|
||||
@@ -1194,7 +1198,6 @@ struct D3D12UniformBuffer
|
||||
D3D12Buffer *buffer;
|
||||
Uint32 writeOffset;
|
||||
Uint32 drawOffset;
|
||||
Uint32 currentBlockSize;
|
||||
};
|
||||
|
||||
// Forward function declarations
|
||||
@@ -1441,6 +1444,8 @@ static void D3D12_INTERNAL_ReleaseTextureContainer(
|
||||
container->textures[i]);
|
||||
}
|
||||
|
||||
SDL_DestroyProperties(container->header.info.props);
|
||||
|
||||
// Containers are just client handles, so we can destroy immediately
|
||||
if (container->debugName) {
|
||||
SDL_free(container->debugName);
|
||||
@@ -1587,6 +1592,7 @@ static void D3D12_INTERNAL_DestroyCommandBuffer(D3D12CommandBuffer *commandBuffe
|
||||
SDL_free(commandBuffer->usedSamplers);
|
||||
SDL_free(commandBuffer->usedGraphicsPipelines);
|
||||
SDL_free(commandBuffer->usedComputePipelines);
|
||||
SDL_free(commandBuffer->usedDescriptorHeaps);
|
||||
SDL_free(commandBuffer->usedUniformBuffers);
|
||||
SDL_free(commandBuffer->textureDownloads);
|
||||
SDL_free(commandBuffer);
|
||||
@@ -2283,6 +2289,28 @@ static bool D3D12_INTERNAL_ExpandStagingDescriptorPool(
|
||||
return true;
|
||||
}
|
||||
|
||||
static void D3D12_INTERNAL_TrackGPUDescriptorHeap(
|
||||
D3D12CommandBuffer *commandBuffer,
|
||||
D3D12DescriptorHeap *descriptorHeap)
|
||||
{
|
||||
Uint32 i;
|
||||
for (i = 0; i < commandBuffer->usedDescriptorHeapCount; i += 1) {
|
||||
if (commandBuffer->usedDescriptorHeaps[i] == descriptorHeap) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (commandBuffer->usedDescriptorHeapCount == commandBuffer->usedDescriptorHeapCapacity) {
|
||||
commandBuffer->usedDescriptorHeapCapacity += 1;
|
||||
commandBuffer->usedDescriptorHeaps = (D3D12DescriptorHeap **)SDL_realloc(
|
||||
commandBuffer->usedDescriptorHeaps,
|
||||
commandBuffer->usedDescriptorHeapCapacity * sizeof(D3D12DescriptorHeap *));
|
||||
}
|
||||
|
||||
commandBuffer->usedDescriptorHeaps[commandBuffer->usedDescriptorHeapCount] = descriptorHeap;
|
||||
commandBuffer->usedDescriptorHeapCount += 1;
|
||||
}
|
||||
|
||||
static D3D12DescriptorHeap *D3D12_INTERNAL_AcquireGPUDescriptorHeapFromPool(
|
||||
D3D12CommandBuffer *commandBuffer,
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE descriptorHeapType)
|
||||
@@ -2304,6 +2332,7 @@ static D3D12DescriptorHeap *D3D12_INTERNAL_AcquireGPUDescriptorHeapFromPool(
|
||||
}
|
||||
SDL_UnlockMutex(pool->lock);
|
||||
|
||||
D3D12_INTERNAL_TrackGPUDescriptorHeap(commandBuffer, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -4496,7 +4525,6 @@ static D3D12UniformBuffer *D3D12_INTERNAL_AcquireUniformBufferFromPool(
|
||||
|
||||
SDL_UnlockMutex(renderer->acquireUniformBufferLock);
|
||||
|
||||
uniformBuffer->currentBlockSize = 0;
|
||||
uniformBuffer->drawOffset = 0;
|
||||
uniformBuffer->writeOffset = 0;
|
||||
|
||||
@@ -4535,6 +4563,7 @@ static void D3D12_INTERNAL_PushUniformData(
|
||||
Uint32 length)
|
||||
{
|
||||
D3D12UniformBuffer *uniformBuffer;
|
||||
Uint32 blockSize;
|
||||
|
||||
if (shaderStage == SDL_GPU_SHADERSTAGE_VERTEX) {
|
||||
if (commandBuffer->vertexUniformBuffers[slotIndex] == NULL) {
|
||||
@@ -4559,13 +4588,13 @@ static void D3D12_INTERNAL_PushUniformData(
|
||||
return;
|
||||
}
|
||||
|
||||
uniformBuffer->currentBlockSize =
|
||||
blockSize =
|
||||
D3D12_INTERNAL_Align(
|
||||
length,
|
||||
256);
|
||||
|
||||
// If there is no more room, acquire a new uniform buffer
|
||||
if (uniformBuffer->writeOffset + uniformBuffer->currentBlockSize >= UNIFORM_BUFFER_SIZE) {
|
||||
if (uniformBuffer->writeOffset + blockSize >= UNIFORM_BUFFER_SIZE) {
|
||||
ID3D12Resource_Unmap(
|
||||
uniformBuffer->buffer->handle,
|
||||
0,
|
||||
@@ -4595,7 +4624,7 @@ static void D3D12_INTERNAL_PushUniformData(
|
||||
data,
|
||||
length);
|
||||
|
||||
uniformBuffer->writeOffset += uniformBuffer->currentBlockSize;
|
||||
uniformBuffer->writeOffset += blockSize;
|
||||
|
||||
if (shaderStage == SDL_GPU_SHADERSTAGE_VERTEX) {
|
||||
commandBuffer->needVertexUniformBufferBind[slotIndex] = true;
|
||||
@@ -7279,6 +7308,11 @@ static bool D3D12_INTERNAL_AllocateCommandBuffer(
|
||||
commandBuffer->usedComputePipelines = (D3D12ComputePipeline **)SDL_calloc(
|
||||
commandBuffer->usedComputePipelineCapacity, sizeof(D3D12ComputePipeline *));
|
||||
|
||||
commandBuffer->usedDescriptorHeapCapacity = 4;
|
||||
commandBuffer->usedDescriptorHeapCount = 0;
|
||||
commandBuffer->usedDescriptorHeaps = (D3D12DescriptorHeap **)SDL_calloc(
|
||||
commandBuffer->usedDescriptorHeapCapacity, sizeof(D3D12DescriptorHeap *));
|
||||
|
||||
commandBuffer->usedUniformBufferCapacity = 4;
|
||||
commandBuffer->usedUniformBufferCount = 0;
|
||||
commandBuffer->usedUniformBuffers = (D3D12UniformBuffer **)SDL_calloc(
|
||||
@@ -7700,13 +7734,13 @@ static bool D3D12_INTERNAL_CleanCommandBuffer(
|
||||
NULL);
|
||||
CHECK_D3D12_ERROR_AND_RETURN("Could not reset command list", false);
|
||||
|
||||
// Return descriptor heaps to pool
|
||||
D3D12_INTERNAL_ReturnGPUDescriptorHeapToPool(
|
||||
renderer,
|
||||
commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV]);
|
||||
D3D12_INTERNAL_ReturnGPUDescriptorHeapToPool(
|
||||
renderer,
|
||||
commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER]);
|
||||
// Return descriptor heaps to pool, pools own their own locks
|
||||
for (i = 0; i < commandBuffer->usedDescriptorHeapCount; i += 1) {
|
||||
D3D12_INTERNAL_ReturnGPUDescriptorHeapToPool(
|
||||
renderer,
|
||||
commandBuffer->usedDescriptorHeaps[i]);
|
||||
}
|
||||
commandBuffer->usedDescriptorHeapCount = 0;
|
||||
|
||||
commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV] = NULL;
|
||||
commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER] = NULL;
|
||||
@@ -8352,6 +8386,7 @@ static bool D3D12_PrepareDriver(SDL_VideoDevice *_this)
|
||||
IDXGIFactory4 *factory4;
|
||||
IDXGIFactory6 *factory6;
|
||||
IDXGIAdapter1 *adapter;
|
||||
bool supports_64UAVs = false;
|
||||
|
||||
// Can we load D3D12?
|
||||
|
||||
@@ -8440,12 +8475,39 @@ static bool D3D12_PrepareDriver(SDL_VideoDevice *_this)
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_COMPILE_TIME_ASSERT(featurelevel, D3D_FEATURE_LEVEL_CHOICE < D3D_FEATURE_LEVEL_11_1);
|
||||
|
||||
// Check feature level 11_1 first, guarantees 64+ UAVs unlike 11_0 Tier1
|
||||
res = D3D12CreateDeviceFunc(
|
||||
(IUnknown *)adapter,
|
||||
D3D_FEATURE_LEVEL_CHOICE,
|
||||
D3D_FEATURE_LEVEL_11_1,
|
||||
D3D_GUID(D3D_IID_ID3D12Device),
|
||||
(void **)&device);
|
||||
|
||||
if (SUCCEEDED(res)) {
|
||||
supports_64UAVs = true;
|
||||
} else {
|
||||
res = D3D12CreateDeviceFunc(
|
||||
(IUnknown *)adapter,
|
||||
D3D_FEATURE_LEVEL_CHOICE,
|
||||
D3D_GUID(D3D_IID_ID3D12Device),
|
||||
(void **)&device);
|
||||
|
||||
if (SUCCEEDED(res)) {
|
||||
D3D12_FEATURE_DATA_D3D12_OPTIONS featureOptions;
|
||||
SDL_zero(featureOptions);
|
||||
|
||||
res = ID3D12Device_CheckFeatureSupport(
|
||||
device,
|
||||
D3D12_FEATURE_D3D12_OPTIONS,
|
||||
&featureOptions,
|
||||
sizeof(featureOptions));
|
||||
if (SUCCEEDED(res) && featureOptions.ResourceBindingTier >= D3D12_RESOURCE_BINDING_TIER_2) {
|
||||
supports_64UAVs = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(res)) {
|
||||
ID3D12Device_Release(device);
|
||||
}
|
||||
@@ -8455,6 +8517,11 @@ static bool D3D12_PrepareDriver(SDL_VideoDevice *_this)
|
||||
SDL_UnloadObject(d3d12Dll);
|
||||
SDL_UnloadObject(dxgiDll);
|
||||
|
||||
if (!supports_64UAVs) {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "D3D12: Tier 2 Resource binding is not supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FAILED(res)) {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "D3D12: Could not create D3D12Device with feature level " D3D_FEATURE_LEVEL_CHOICE_STR);
|
||||
return false;
|
||||
|
||||
@@ -888,6 +888,7 @@ static void METAL_INTERNAL_DestroyTextureContainer(
|
||||
container->textures[i]->handle = nil;
|
||||
SDL_free(container->textures[i]);
|
||||
}
|
||||
SDL_DestroyProperties(container->header.info.props);
|
||||
if (container->debugName != NULL) {
|
||||
SDL_free(container->debugName);
|
||||
}
|
||||
@@ -1777,7 +1778,8 @@ static void METAL_UploadToTexture(
|
||||
copyFromBuffer:bufferContainer->activeBuffer->handle
|
||||
sourceOffset:source->offset
|
||||
sourceBytesPerRow:BytesPerRow(destination->w, textureContainer->header.info.format)
|
||||
sourceBytesPerImage:SDL_CalculateGPUTextureFormatSize(textureContainer->header.info.format, destination->w, destination->h, destination->d)
|
||||
// sourceBytesPerImage expects the stride between 2D images (slices) of a 3D texture, not the size of the entire region
|
||||
sourceBytesPerImage:SDL_CalculateGPUTextureFormatSize(textureContainer->header.info.format, destination->w, destination->h, 1)
|
||||
sourceSize:MTLSizeMake(destination->w, destination->h, destination->d)
|
||||
toTexture:metalTexture->handle
|
||||
destinationSlice:destination->layer
|
||||
|
||||
+103
-36
@@ -1108,6 +1108,7 @@ typedef struct VulkanCommandBuffer
|
||||
VulkanFenceHandle *inFlightFence;
|
||||
bool autoReleaseFence;
|
||||
|
||||
bool swapchainRequested;
|
||||
bool isDefrag; // Whether this CB was created for defragging
|
||||
} VulkanCommandBuffer;
|
||||
|
||||
@@ -1142,6 +1143,7 @@ struct VulkanRenderer
|
||||
VulkanExtensions supports;
|
||||
bool supportsDebugUtils;
|
||||
bool supportsColorspace;
|
||||
bool supportsPhysicalDeviceProperties2;
|
||||
bool supportsFillModeNonSolid;
|
||||
bool supportsMultiDrawIndirect;
|
||||
|
||||
@@ -1277,13 +1279,20 @@ static inline const char *VkErrorMessages(VkResult code)
|
||||
#undef ERR_TO_STR
|
||||
}
|
||||
|
||||
#define SET_ERROR_AND_RETURN(fmt, msg, ret) \
|
||||
#define SET_ERROR(fmt, msg) \
|
||||
do { \
|
||||
if (renderer->debugMode) { \
|
||||
SDL_LogError(SDL_LOG_CATEGORY_GPU, fmt, msg); \
|
||||
} \
|
||||
SDL_SetError((fmt), (msg)); \
|
||||
return ret; \
|
||||
} while (0)
|
||||
|
||||
#define SET_STRING_ERROR(msg) SET_ERROR("%s", msg)
|
||||
|
||||
#define SET_ERROR_AND_RETURN(fmt, msg, ret) \
|
||||
do { \
|
||||
SET_ERROR(fmt, msg); \
|
||||
return ret; \
|
||||
} while (0)
|
||||
|
||||
#define SET_STRING_ERROR_AND_RETURN(msg, ret) SET_ERROR_AND_RETURN("%s", msg, ret)
|
||||
@@ -5884,7 +5893,10 @@ static VulkanTexture *VULKAN_INTERNAL_CreateTexture(
|
||||
VULKAN_TEXTURE_USAGE_MODE_UNINITIALIZED,
|
||||
texture);
|
||||
VULKAN_INTERNAL_TrackTexture(barrierCommandBuffer, texture);
|
||||
VULKAN_Submit((SDL_GPUCommandBuffer *)barrierCommandBuffer);
|
||||
if (!VULKAN_Submit((SDL_GPUCommandBuffer *)barrierCommandBuffer)) {
|
||||
VULKAN_INTERNAL_DestroyTexture(renderer, texture);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return texture;
|
||||
@@ -6081,7 +6093,6 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass(
|
||||
colorAttachmentReferences[colorAttachmentReferenceCount].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
attachmentDescriptionCount += 1;
|
||||
colorAttachmentReferenceCount += 1;
|
||||
|
||||
if (colorTargetInfos[i].store_op == SDL_GPU_STOREOP_RESOLVE || colorTargetInfos[i].store_op == SDL_GPU_STOREOP_RESOLVE_AND_STORE) {
|
||||
VulkanTextureContainer *resolveContainer = (VulkanTextureContainer *)colorTargetInfos[i].resolve_texture;
|
||||
@@ -6096,12 +6107,16 @@ static VkRenderPass VULKAN_INTERNAL_CreateRenderPass(
|
||||
attachmentDescriptions[attachmentDescriptionCount].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
attachmentDescriptions[attachmentDescriptionCount].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
resolveReferences[resolveReferenceCount].attachment = attachmentDescriptionCount;
|
||||
resolveReferences[resolveReferenceCount].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
resolveReferences[colorAttachmentReferenceCount].attachment = attachmentDescriptionCount;
|
||||
resolveReferences[colorAttachmentReferenceCount].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
attachmentDescriptionCount += 1;
|
||||
resolveReferenceCount += 1;
|
||||
} else {
|
||||
resolveReferences[colorAttachmentReferenceCount].attachment = VK_ATTACHMENT_UNUSED;
|
||||
}
|
||||
|
||||
colorAttachmentReferenceCount += 1;
|
||||
}
|
||||
|
||||
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
@@ -6951,6 +6966,8 @@ static void VULKAN_ReleaseTexture(
|
||||
VULKAN_INTERNAL_ReleaseTexture(renderer, vulkanTextureContainer->textures[i]);
|
||||
}
|
||||
|
||||
SDL_DestroyProperties(vulkanTextureContainer->header.info.props);
|
||||
|
||||
// Containers are just client handles, so we can destroy immediately
|
||||
if (vulkanTextureContainer->debugName != NULL) {
|
||||
SDL_free(vulkanTextureContainer->debugName);
|
||||
@@ -7896,15 +7913,17 @@ static void VULKAN_BeginRenderPass(
|
||||
|
||||
clearValues = SDL_stack_alloc(VkClearValue, clearCount);
|
||||
|
||||
for (i = 0; i < totalColorAttachmentCount; i += 1) {
|
||||
clearValues[i].color.float32[0] = colorTargetInfos[i].clear_color.r;
|
||||
clearValues[i].color.float32[1] = colorTargetInfos[i].clear_color.g;
|
||||
clearValues[i].color.float32[2] = colorTargetInfos[i].clear_color.b;
|
||||
clearValues[i].color.float32[3] = colorTargetInfos[i].clear_color.a;
|
||||
int clearIndex = 0;
|
||||
for (i = 0; i < numColorTargets; i += 1) {
|
||||
clearValues[clearIndex].color.float32[0] = colorTargetInfos[i].clear_color.r;
|
||||
clearValues[clearIndex].color.float32[1] = colorTargetInfos[i].clear_color.g;
|
||||
clearValues[clearIndex].color.float32[2] = colorTargetInfos[i].clear_color.b;
|
||||
clearValues[clearIndex].color.float32[3] = colorTargetInfos[i].clear_color.a;
|
||||
clearIndex += 1;
|
||||
|
||||
if (colorTargetInfos[i].store_op == SDL_GPU_STOREOP_RESOLVE || colorTargetInfos[i].store_op == SDL_GPU_STOREOP_RESOLVE_AND_STORE) {
|
||||
// Skip over the resolve texture, we're not clearing it
|
||||
i += 1;
|
||||
clearIndex += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8592,7 +8611,7 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets(
|
||||
dynamicOffsetCount,
|
||||
dynamicOffsets);
|
||||
|
||||
commandBuffer->needNewVertexUniformOffsets = false;
|
||||
commandBuffer->needNewComputeUniformOffsets = false;
|
||||
}
|
||||
|
||||
static void VULKAN_DispatchCompute(
|
||||
@@ -9395,6 +9414,8 @@ static bool VULKAN_INTERNAL_AllocateCommandBuffer(
|
||||
commandBuffer->usedUniformBuffers = SDL_malloc(
|
||||
commandBuffer->usedUniformBufferCapacity * sizeof(VulkanUniformBuffer *));
|
||||
|
||||
commandBuffer->swapchainRequested = false;
|
||||
|
||||
// Pool it!
|
||||
|
||||
vulkanCommandPool->inactiveCommandBuffers[vulkanCommandPool->inactiveCommandBufferCount] = commandBuffer;
|
||||
@@ -9505,7 +9526,8 @@ static SDL_GPUCommandBuffer *VULKAN_AcquireCommandBuffer(
|
||||
VulkanCommandBuffer *commandBuffer =
|
||||
VULKAN_INTERNAL_GetInactiveCommandBufferFromPool(renderer, threadID);
|
||||
|
||||
commandBuffer->descriptorSetCache = VULKAN_INTERNAL_AcquireDescriptorSetCache(renderer);
|
||||
DescriptorSetCache *descriptorSetCache =
|
||||
VULKAN_INTERNAL_AcquireDescriptorSetCache(renderer);
|
||||
|
||||
SDL_UnlockMutex(renderer->acquireCommandBufferLock);
|
||||
|
||||
@@ -9513,6 +9535,8 @@ static SDL_GPUCommandBuffer *VULKAN_AcquireCommandBuffer(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
commandBuffer->descriptorSetCache = descriptorSetCache;
|
||||
|
||||
// Reset state
|
||||
|
||||
commandBuffer->currentComputePipeline = NULL;
|
||||
@@ -9577,6 +9601,7 @@ static SDL_GPUCommandBuffer *VULKAN_AcquireCommandBuffer(
|
||||
|
||||
commandBuffer->autoReleaseFence = true;
|
||||
|
||||
commandBuffer->swapchainRequested = false;
|
||||
commandBuffer->isDefrag = 0;
|
||||
|
||||
/* Reset the command buffer here to avoid resets being called
|
||||
@@ -9663,6 +9688,13 @@ static bool VULKAN_INTERNAL_OnWindowResize(void *userdata, SDL_Event *e)
|
||||
data->swapchainCreateHeight = e->window.data2;
|
||||
}
|
||||
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
if (e->type == SDL_EVENT_DID_ENTER_BACKGROUND) {
|
||||
data = VULKAN_INTERNAL_FetchWindowData(w);
|
||||
data->needsSwapchainRecreate = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -9925,6 +9957,14 @@ static bool VULKAN_INTERNAL_AcquireSwapchainTexture(
|
||||
SET_STRING_ERROR_AND_RETURN("Cannot acquire a swapchain texture from an unclaimed window!", false);
|
||||
}
|
||||
|
||||
// The command buffer is flagged for cleanup when the swapchain is requested as a cleanup timing mechanism
|
||||
vulkanCommandBuffer->swapchainRequested = true;
|
||||
|
||||
if (window->flags & SDL_WINDOW_HIDDEN) {
|
||||
// Edge case, texture is filled in with NULL but not an error
|
||||
return true;
|
||||
}
|
||||
|
||||
// If window data marked as needing swapchain recreate, try to recreate
|
||||
if (windowData->needsSwapchainRecreate) {
|
||||
Uint32 recreateSwapchainResult = VULKAN_INTERNAL_RecreateSwapchain(renderer, windowData);
|
||||
@@ -9942,13 +9982,6 @@ static bool VULKAN_INTERNAL_AcquireSwapchainTexture(
|
||||
}
|
||||
}
|
||||
|
||||
if (swapchainTextureWidth) {
|
||||
*swapchainTextureWidth = windowData->width;
|
||||
}
|
||||
if (swapchainTextureHeight) {
|
||||
*swapchainTextureHeight = windowData->height;
|
||||
}
|
||||
|
||||
if (windowData->inFlightFences[windowData->frameCounter] != NULL) {
|
||||
if (block) {
|
||||
// If we are blocking, just wait for the fence!
|
||||
@@ -10000,6 +10033,14 @@ static bool VULKAN_INTERNAL_AcquireSwapchainTexture(
|
||||
}
|
||||
}
|
||||
|
||||
if (swapchainTextureWidth) {
|
||||
*swapchainTextureWidth = windowData->width;
|
||||
}
|
||||
|
||||
if (swapchainTextureHeight) {
|
||||
*swapchainTextureHeight = windowData->height;
|
||||
}
|
||||
|
||||
swapchainTextureContainer = &windowData->textureContainers[swapchainImageIndex];
|
||||
|
||||
// We need a special execution dependency with pWaitDstStageMask or image transition can start before acquire finishes
|
||||
@@ -10377,6 +10418,7 @@ static void VULKAN_INTERNAL_CleanCommandBuffer(
|
||||
commandBuffer->presentDataCount = 0;
|
||||
commandBuffer->waitSemaphoreCount = 0;
|
||||
commandBuffer->signalSemaphoreCount = 0;
|
||||
commandBuffer->swapchainRequested = false;
|
||||
|
||||
// Reset defrag state
|
||||
|
||||
@@ -10474,11 +10516,18 @@ static bool VULKAN_Wait(
|
||||
VkResult result;
|
||||
Sint32 i;
|
||||
|
||||
SDL_LockMutex(renderer->submitLock);
|
||||
|
||||
result = renderer->vkDeviceWaitIdle(renderer->logicalDevice);
|
||||
|
||||
CHECK_VULKAN_ERROR_AND_RETURN(result, vkDeviceWaitIdle, false);
|
||||
|
||||
SDL_LockMutex(renderer->submitLock);
|
||||
if (result != VK_SUCCESS) {
|
||||
if (renderer->debugMode) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s %s", "vkDeviceWaitIdle", VkErrorMessages(result));
|
||||
}
|
||||
SDL_SetError("%s %s", "vkDeviceWaitIdle", VkErrorMessages(result));
|
||||
SDL_UnlockMutex(renderer->submitLock);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1) {
|
||||
commandBuffer = renderer->submittedCommandBuffers[i];
|
||||
@@ -10533,7 +10582,7 @@ static bool VULKAN_Submit(
|
||||
VulkanTextureSubresource *swapchainTextureSubresource;
|
||||
VulkanMemorySubAllocator *allocator;
|
||||
bool performCleanups =
|
||||
(renderer->claimedWindowCount > 0 && vulkanCommandBuffer->presentDataCount > 0) ||
|
||||
(renderer->claimedWindowCount > 0 && vulkanCommandBuffer->swapchainRequested) ||
|
||||
renderer->claimedWindowCount == 0;
|
||||
|
||||
SDL_LockMutex(renderer->submitLock);
|
||||
@@ -10625,7 +10674,13 @@ static bool VULKAN_Submit(
|
||||
presentData->windowData->inFlightFences[presentData->windowData->frameCounter] = (SDL_GPUFence*)vulkanCommandBuffer->inFlightFence;
|
||||
(void)SDL_AtomicIncRef(&vulkanCommandBuffer->inFlightFence->referenceCount);
|
||||
|
||||
if (presentResult == VK_SUBOPTIMAL_KHR || presentResult == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||
// On the Android platform, VK_SUBOPTIMAL_KHR is returned whenever the device is rotated. We'll just ignore this for now.
|
||||
#ifndef SDL_PLATFORM_ANDROID
|
||||
if (presentResult == VK_SUBOPTIMAL_KHR) {
|
||||
presentData->windowData->needsSwapchainRecreate = true;
|
||||
}
|
||||
#endif
|
||||
if (presentResult == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||
presentData->windowData->needsSwapchainRecreate = true;
|
||||
}
|
||||
} else {
|
||||
@@ -11003,7 +11058,8 @@ static Uint8 VULKAN_INTERNAL_CheckInstanceExtensions(
|
||||
const char **requiredExtensions,
|
||||
Uint32 requiredExtensionsLength,
|
||||
bool *supportsDebugUtils,
|
||||
bool *supportsColorspace)
|
||||
bool *supportsColorspace,
|
||||
bool *supportsPhysicalDeviceProperties2)
|
||||
{
|
||||
Uint32 extensionCount, i;
|
||||
VkExtensionProperties *availableExtensions;
|
||||
@@ -11042,6 +11098,12 @@ static Uint8 VULKAN_INTERNAL_CheckInstanceExtensions(
|
||||
availableExtensions,
|
||||
extensionCount);
|
||||
|
||||
// Only needed for KHR_driver_properties!
|
||||
*supportsPhysicalDeviceProperties2 = SupportsInstanceExtension(
|
||||
VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
|
||||
availableExtensions,
|
||||
extensionCount);
|
||||
|
||||
SDL_free(availableExtensions);
|
||||
return allExtensionsSupported;
|
||||
}
|
||||
@@ -11152,10 +11214,6 @@ static Uint8 VULKAN_INTERNAL_CreateInstance(VulkanRenderer *renderer)
|
||||
instanceExtensionCount + 4);
|
||||
SDL_memcpy((void *)instanceExtensionNames, originalInstanceExtensionNames, instanceExtensionCount * sizeof(const char *));
|
||||
|
||||
// Core since 1.1
|
||||
instanceExtensionNames[instanceExtensionCount++] =
|
||||
VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME;
|
||||
|
||||
#ifdef SDL_PLATFORM_APPLE
|
||||
instanceExtensionNames[instanceExtensionCount++] =
|
||||
VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME;
|
||||
@@ -11166,7 +11224,8 @@ static Uint8 VULKAN_INTERNAL_CreateInstance(VulkanRenderer *renderer)
|
||||
instanceExtensionNames,
|
||||
instanceExtensionCount,
|
||||
&renderer->supportsDebugUtils,
|
||||
&renderer->supportsColorspace)) {
|
||||
&renderer->supportsColorspace,
|
||||
&renderer->supportsPhysicalDeviceProperties2)) {
|
||||
SDL_stack_free((char *)instanceExtensionNames);
|
||||
SET_STRING_ERROR_AND_RETURN("Required Vulkan instance extensions not supported", false);
|
||||
}
|
||||
@@ -11188,6 +11247,12 @@ static Uint8 VULKAN_INTERNAL_CreateInstance(VulkanRenderer *renderer)
|
||||
VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME;
|
||||
}
|
||||
|
||||
if (renderer->supportsPhysicalDeviceProperties2) {
|
||||
// Append KHR_physical_device_properties2 extension
|
||||
instanceExtensionNames[instanceExtensionCount++] =
|
||||
VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME;
|
||||
}
|
||||
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
createInfo.pNext = NULL;
|
||||
createInfo.flags = createFlags;
|
||||
@@ -11686,7 +11751,7 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S
|
||||
renderer = (VulkanRenderer *)SDL_calloc(1, sizeof(*renderer));
|
||||
if (!renderer) {
|
||||
SDL_Vulkan_UnloadLibrary();
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
renderer->debugMode = debugMode;
|
||||
@@ -11694,9 +11759,10 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S
|
||||
renderer->allowedFramesInFlight = 2;
|
||||
|
||||
if (!VULKAN_INTERNAL_PrepareVulkan(renderer)) {
|
||||
SET_STRING_ERROR("Failed to initialize Vulkan!");
|
||||
SDL_free(renderer);
|
||||
SDL_Vulkan_UnloadLibrary();
|
||||
SET_STRING_ERROR_AND_RETURN("Failed to initialize Vulkan!", NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "SDL_GPU Driver: Vulkan");
|
||||
@@ -11722,13 +11788,14 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S
|
||||
|
||||
if (!VULKAN_INTERNAL_CreateLogicalDevice(
|
||||
renderer)) {
|
||||
SET_STRING_ERROR("Failed to create logical device!");
|
||||
SDL_free(renderer);
|
||||
SDL_Vulkan_UnloadLibrary();
|
||||
SET_STRING_ERROR_AND_RETURN("Failed to create logical device!", NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// FIXME: just move this into this function
|
||||
result = (SDL_GPUDevice *)SDL_malloc(sizeof(SDL_GPUDevice));
|
||||
result = (SDL_GPUDevice *)SDL_calloc(1, sizeof(SDL_GPUDevice));
|
||||
ASSIGN_DRIVER(VULKAN)
|
||||
|
||||
result->driverData = (SDL_GPURenderer *)renderer;
|
||||
|
||||
@@ -1117,13 +1117,12 @@ bool SDL_SYS_HapticResume(SDL_Haptic *haptic)
|
||||
*/
|
||||
bool SDL_SYS_HapticStopAll(SDL_Haptic *haptic)
|
||||
{
|
||||
int i, ret;
|
||||
int i;
|
||||
|
||||
// Linux does not support this natively so we have to loop.
|
||||
for (i = 0; i < haptic->neffects; i++) {
|
||||
if (haptic->effects[i].hweffect != NULL) {
|
||||
ret = SDL_SYS_HapticStopEffect(haptic, &haptic->effects[i]);
|
||||
if (ret < 0) {
|
||||
if (!SDL_SYS_HapticStopEffect(haptic, &haptic->effects[i])) {
|
||||
return SDL_SetError("Haptic: Error while trying to stop all playing effects.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,11 +31,7 @@
|
||||
/*
|
||||
* External stuff.
|
||||
*/
|
||||
#ifdef SDL_VIDEO_DRIVER_WINDOWS
|
||||
extern HWND SDL_HelperWindow;
|
||||
#else
|
||||
static const HWND SDL_HelperWindow = NULL;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Internal stuff.
|
||||
|
||||
+47
-19
@@ -71,6 +71,11 @@ extern "C" {
|
||||
#define DETACH_KERNEL_DRIVER
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:5287) /* operands are different enum types */
|
||||
#endif
|
||||
|
||||
/* Uncomment to enable the retrieval of Usage and Usage Page in
|
||||
hid_enumerate(). Warning, on platforms different from FreeBSD
|
||||
this is very invasive as it requires the detach
|
||||
@@ -255,19 +260,19 @@ static int get_usage(uint8_t *report_descriptor, size_t size,
|
||||
}
|
||||
|
||||
if (key_cmd == 0x4) {
|
||||
*usage_page = get_bytes(report_descriptor, size, data_len, i);
|
||||
*usage_page = (unsigned short)get_bytes(report_descriptor, size, data_len, i);
|
||||
usage_page_found = 1;
|
||||
//printf("Usage Page: %x\n", (uint32_t)*usage_page);
|
||||
}
|
||||
if (key_cmd == 0x8) {
|
||||
if (data_len == 4) { /* Usages 5.5 / Usage Page 6.2.2.7 */
|
||||
*usage_page = get_bytes(report_descriptor, size, 2, i + 2);
|
||||
*usage_page = (unsigned short)get_bytes(report_descriptor, size, 2, i + 2);
|
||||
usage_page_found = 1;
|
||||
*usage = get_bytes(report_descriptor, size, 2, i);
|
||||
*usage = (unsigned short)get_bytes(report_descriptor, size, 2, i);
|
||||
usage_found = 1;
|
||||
}
|
||||
else {
|
||||
*usage = get_bytes(report_descriptor, size, data_len, i);
|
||||
*usage = (unsigned short)get_bytes(report_descriptor, size, data_len, i);
|
||||
usage_found = 1;
|
||||
}
|
||||
//printf("Usage: %x\n", (uint32_t)*usage);
|
||||
@@ -635,7 +640,7 @@ static int hid_get_report_descriptor_libusb(libusb_device_handle *handle, int in
|
||||
/* Get the HID Report Descriptor.
|
||||
See USB HID Specification, section 7.1.1
|
||||
*/
|
||||
int res = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_RECIPIENT_INTERFACE, LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_REPORT << 8), interface_num, tmp, expected_report_descriptor_size, 5000);
|
||||
int res = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_RECIPIENT_INTERFACE, LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_REPORT << 8), (uint16_t)interface_num, tmp, expected_report_descriptor_size, 5000);
|
||||
if (res >= 0) {
|
||||
if (res > (int)buf_size)
|
||||
res = (int)buf_size;
|
||||
@@ -666,6 +671,8 @@ static void fill_device_info_usage(struct hid_device_info *cur_dev, libusb_devic
|
||||
|
||||
cur_dev->usage_page = page;
|
||||
cur_dev->usage = usage;
|
||||
|
||||
free(hid_report_descriptor);
|
||||
}
|
||||
|
||||
#ifdef INVASIVE_GET_USAGE
|
||||
@@ -918,6 +925,22 @@ static int should_enumerate_interface(unsigned short vendor_id, const struct lib
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int libusb_blacklist(unsigned short vendor_id, unsigned short product_id)
|
||||
{
|
||||
size_t i;
|
||||
static const struct { unsigned short vid; unsigned short pid; } known_bad[] = {
|
||||
{ 0x1532, 0x0227 } /* Razer Huntsman Gaming keyboard - long delay asking for device details */
|
||||
};
|
||||
|
||||
for (i = 0; i < (sizeof(known_bad)/sizeof(known_bad[0])); i++) {
|
||||
if ((vendor_id == known_bad[i].vid) && (product_id == known_bad[i].pid || known_bad[i].pid == 0x0000)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
|
||||
{
|
||||
libusb_device **devs;
|
||||
@@ -948,7 +971,8 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
||||
unsigned short dev_pid = desc.idProduct;
|
||||
|
||||
if ((vendor_id != 0x0 && vendor_id != dev_vid) ||
|
||||
(product_id != 0x0 && product_id != dev_pid)) {
|
||||
(product_id != 0x0 && product_id != dev_pid) ||
|
||||
libusb_blacklist(dev_vid, dev_pid)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1169,7 +1193,7 @@ static void *read_thread(void *param)
|
||||
dev->transfer = libusb_alloc_transfer(0);
|
||||
libusb_fill_interrupt_transfer(dev->transfer,
|
||||
dev->device_handle,
|
||||
dev->input_endpoint,
|
||||
(unsigned char)dev->input_endpoint,
|
||||
buf,
|
||||
(int) length,
|
||||
read_callback,
|
||||
@@ -1588,8 +1612,8 @@ int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t
|
||||
res = libusb_control_transfer(dev->device_handle,
|
||||
LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT,
|
||||
0x09/*HID Set_Report*/,
|
||||
(2/*HID output*/ << 8) | report_number,
|
||||
dev->interface,
|
||||
(uint16_t)((2/*HID output*/ << 8) | report_number),
|
||||
(uint16_t)dev->interface,
|
||||
(unsigned char *)data, (uint16_t)length,
|
||||
1000/*timeout millis*/);
|
||||
|
||||
@@ -1605,7 +1629,7 @@ int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t
|
||||
/* Use the interrupt out endpoint */
|
||||
int actual_length;
|
||||
res = libusb_interrupt_transfer(dev->device_handle,
|
||||
dev->output_endpoint,
|
||||
(unsigned char)dev->output_endpoint,
|
||||
(unsigned char*)data,
|
||||
(int) length,
|
||||
&actual_length, 1000);
|
||||
@@ -1754,8 +1778,8 @@ int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char
|
||||
res = libusb_control_transfer(dev->device_handle,
|
||||
LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT,
|
||||
0x09/*HID set_report*/,
|
||||
(3/*HID feature*/ << 8) | report_number,
|
||||
dev->interface,
|
||||
(uint16_t)((3/*HID feature*/ << 8) | report_number),
|
||||
(uint16_t)dev->interface,
|
||||
(unsigned char *)data, (uint16_t)length,
|
||||
1000/*timeout millis*/);
|
||||
|
||||
@@ -1785,8 +1809,8 @@ int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data,
|
||||
res = libusb_control_transfer(dev->device_handle,
|
||||
LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN,
|
||||
0x01/*HID get_report*/,
|
||||
(3/*HID feature*/ << 8) | report_number,
|
||||
dev->interface,
|
||||
(uint16_t)((3/*HID feature*/ << 8) | report_number),
|
||||
(uint16_t)dev->interface,
|
||||
(unsigned char *)data, (uint16_t)length,
|
||||
1000/*timeout millis*/);
|
||||
|
||||
@@ -1815,8 +1839,8 @@ int HID_API_EXPORT HID_API_CALL hid_get_input_report(hid_device *dev, unsigned c
|
||||
res = libusb_control_transfer(dev->device_handle,
|
||||
LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN,
|
||||
0x01/*HID get_report*/,
|
||||
(1/*HID Input*/ << 8) | report_number,
|
||||
dev->interface,
|
||||
(uint16_t)((1/*HID Input*/ << 8) | report_number),
|
||||
(uint16_t)dev->interface,
|
||||
(unsigned char *)data, (uint16_t)length,
|
||||
1000/*timeout millis*/);
|
||||
|
||||
@@ -1908,7 +1932,7 @@ int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index
|
||||
{
|
||||
wchar_t *str;
|
||||
|
||||
str = get_usb_string(dev->device_handle, string_index);
|
||||
str = get_usb_string(dev->device_handle, (uint8_t)string_index);
|
||||
if (str) {
|
||||
wcsncpy(string, str, maxlen);
|
||||
string[maxlen-1] = L'\0';
|
||||
@@ -2096,7 +2120,7 @@ uint16_t get_usb_code_for_current_locale(void)
|
||||
/* Chop off the encoding part, and make it lower case. */
|
||||
ptr = search_string;
|
||||
while (*ptr) {
|
||||
*ptr = tolower(*ptr);
|
||||
*ptr = (char)tolower(*ptr);
|
||||
if (*ptr == '.') {
|
||||
*ptr = '\0';
|
||||
break;
|
||||
@@ -2117,7 +2141,7 @@ uint16_t get_usb_code_for_current_locale(void)
|
||||
/* Chop off the variant. Chop it off at the '_'. */
|
||||
ptr = search_string;
|
||||
while (*ptr) {
|
||||
*ptr = tolower(*ptr);
|
||||
*ptr = (char)tolower(*ptr);
|
||||
if (*ptr == '_') {
|
||||
*ptr = '\0';
|
||||
break;
|
||||
@@ -2140,6 +2164,10 @@ uint16_t get_usb_code_for_current_locale(void)
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -134,7 +134,6 @@ static wchar_t *utf8_to_wchar_t(const char *utf8)
|
||||
* Use register_error_str(NULL) to free the error message completely. */
|
||||
static void register_error_str(wchar_t **error_str, const char *msg)
|
||||
{
|
||||
free(*error_str);
|
||||
#ifdef HIDAPI_USING_SDL_RUNTIME
|
||||
/* Thread-safe error handling */
|
||||
if (msg) {
|
||||
@@ -143,6 +142,7 @@ static void register_error_str(wchar_t **error_str, const char *msg)
|
||||
SDL_ClearError();
|
||||
}
|
||||
#else
|
||||
free(*error_str);
|
||||
*error_str = utf8_to_wchar_t(msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -949,6 +949,7 @@ static int hid_blacklist(unsigned short vendor_id, unsigned short product_id)
|
||||
{ 0x0D8C, 0x0014 }, /* Sharkoon Skiller SGH2 headset - causes deadlock asking for device details */
|
||||
{ 0x1532, 0x0109 }, /* Razer Lycosa Gaming keyboard - causes deadlock asking for device details */
|
||||
{ 0x1532, 0x010B }, /* Razer Arctosa Gaming keyboard - causes deadlock asking for device details */
|
||||
{ 0x1532, 0x0227 }, /* Razer Huntsman Gaming keyboard - long delay asking for device details */
|
||||
{ 0x1B1C, 0x1B3D }, /* Corsair Gaming keyboard - causes deadlock asking for device details */
|
||||
{ 0x1CCF, 0x0000 } /* All Konami Amusement Devices - causes deadlock asking for device details */
|
||||
};
|
||||
@@ -1398,6 +1399,11 @@ int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char
|
||||
}
|
||||
}
|
||||
if (!res) {
|
||||
if (GetLastError() == ERROR_OPERATION_ABORTED) {
|
||||
/* The read request was issued on another thread.
|
||||
This is harmless, so just ignore it. */
|
||||
return 0;
|
||||
}
|
||||
register_winapi_error(dev, L"hid_read_timeout/GetOverlappedResult");
|
||||
}
|
||||
|
||||
|
||||
@@ -455,7 +455,8 @@ static bool SDLCALL fd_flush(void *userdata, SDL_IOStatus *status)
|
||||
result = SDL_fdatasync(iodata->fd);
|
||||
} while (result < 0 && errno == EINTR);
|
||||
|
||||
if (result < 0) {
|
||||
// We get EINVAL when flushing a pipe, just make that a no-op
|
||||
if (result < 0 && errno != EINVAL) {
|
||||
return SDL_SetError("Error flushing datastream: %s", strerror(errno));
|
||||
}
|
||||
return true;
|
||||
|
||||
+74
-22
@@ -149,6 +149,51 @@ static SDL_vidpid_list SDL_ignored_gamepads = {
|
||||
false
|
||||
};
|
||||
|
||||
/*
|
||||
List of words in gamepad names that indicate that the gamepad should not be detected.
|
||||
See also `initial_blacklist_devices` in SDL_joystick.c
|
||||
*/
|
||||
|
||||
enum SDL_GamepadBlacklistWordsPosition {
|
||||
GAMEPAD_BLACKLIST_BEGIN,
|
||||
GAMEPAD_BLACKLIST_END,
|
||||
GAMEPAD_BLACKLIST_ANYWHERE,
|
||||
};
|
||||
|
||||
struct SDL_GamepadBlacklistWords {
|
||||
const char* str;
|
||||
enum SDL_GamepadBlacklistWordsPosition pos;
|
||||
};
|
||||
|
||||
static const struct SDL_GamepadBlacklistWords SDL_gamepad_blacklist_words[] = {
|
||||
#ifdef SDL_PLATFORM_LINUX
|
||||
{" Motion Sensors", GAMEPAD_BLACKLIST_END}, // Don't treat the PS3 and PS4 motion controls as a separate gamepad
|
||||
{" IMU", GAMEPAD_BLACKLIST_END}, // Don't treat the Nintendo IMU as a separate gamepad
|
||||
{" Touchpad", GAMEPAD_BLACKLIST_END}, // "Sony Interactive Entertainment DualSense Wireless Controller Touchpad"
|
||||
|
||||
// Don't treat the Wii extension controls as a separate gamepad
|
||||
{" Accelerometer", GAMEPAD_BLACKLIST_END},
|
||||
{" IR", GAMEPAD_BLACKLIST_END},
|
||||
{" Motion Plus", GAMEPAD_BLACKLIST_END},
|
||||
{" Nunchuk", GAMEPAD_BLACKLIST_END},
|
||||
#endif
|
||||
|
||||
// The Google Pixel fingerprint sensor, as well as other fingerprint sensors, reports itself as a joystick
|
||||
{"uinput-", GAMEPAD_BLACKLIST_BEGIN},
|
||||
|
||||
{"Synaptics ", GAMEPAD_BLACKLIST_ANYWHERE}, // "Synaptics TM2768-001", "SynPS/2 Synaptics TouchPad"
|
||||
{"Trackpad", GAMEPAD_BLACKLIST_ANYWHERE},
|
||||
{"Clickpad", GAMEPAD_BLACKLIST_ANYWHERE},
|
||||
// "PG-90215 Keyboard", "Usb Keyboard Usb Keyboard Consumer Control", "Framework Laptop 16 Keyboard Module - ISO System Control"
|
||||
{" Keyboard", GAMEPAD_BLACKLIST_ANYWHERE},
|
||||
{" Laptop ", GAMEPAD_BLACKLIST_ANYWHERE}, // "Framework Laptop 16 Numpad Module System Control"
|
||||
{"Mouse ", GAMEPAD_BLACKLIST_BEGIN}, // "Mouse passthrough"
|
||||
{" Pen", GAMEPAD_BLACKLIST_END}, // "Wacom One by Wacom S Pen"
|
||||
{" Finger", GAMEPAD_BLACKLIST_END}, // "Wacom HID 495F Finger"
|
||||
{" LED ", GAMEPAD_BLACKLIST_ANYWHERE}, // "ASRock LED Controller"
|
||||
{" Thelio ", GAMEPAD_BLACKLIST_ANYWHERE}, // "System76 Thelio Io 2"
|
||||
};
|
||||
|
||||
static GamepadMapping_t *SDL_PrivateAddMappingForGUID(SDL_GUID jGUID, const char *mappingString, bool *existing, SDL_GamepadMappingPriority priority);
|
||||
static void SDL_PrivateLoadButtonMapping(SDL_Gamepad *gamepad, GamepadMapping_t *pGamepadMapping);
|
||||
static GamepadMapping_t *SDL_PrivateGetGamepadMapping(SDL_JoystickID instance_id, bool create_mapping);
|
||||
@@ -311,7 +356,7 @@ void SDL_PrivateGamepadAdded(SDL_JoystickID instance_id)
|
||||
{
|
||||
SDL_Event event;
|
||||
|
||||
if (!SDL_gamepads_initialized) {
|
||||
if (!SDL_gamepads_initialized || SDL_IsJoystickBeingAdded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -913,7 +958,7 @@ static GamepadMapping_t *SDL_PrivateMatchGamepadMappingForGUID(SDL_GUID guid, bo
|
||||
// An exact match, including CRC
|
||||
return mapping;
|
||||
} else if (crc && exact_match_crc) {
|
||||
return NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!best_match) {
|
||||
@@ -1786,6 +1831,11 @@ static GamepadMapping_t *SDL_PrivateGenerateAutomaticGamepadMapping(const char *
|
||||
char name_string[128];
|
||||
char mapping[1024];
|
||||
|
||||
// Remove the CRC from the GUID
|
||||
// We already know that this GUID doesn't have a mapping without the CRC, and we want newly
|
||||
// added mappings without a CRC to override this mapping.
|
||||
SDL_SetJoystickGUIDCRC(&guid, 0);
|
||||
|
||||
// Remove any commas in the name
|
||||
SDL_strlcpy(name_string, name, sizeof(name_string));
|
||||
{
|
||||
@@ -2660,27 +2710,29 @@ bool SDL_IsGamepad(SDL_JoystickID instance_id)
|
||||
*/
|
||||
bool SDL_ShouldIgnoreGamepad(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name)
|
||||
{
|
||||
#ifdef SDL_PLATFORM_LINUX
|
||||
if (SDL_endswith(name, " Motion Sensors")) {
|
||||
// Don't treat the PS3 and PS4 motion controls as a separate gamepad
|
||||
return true;
|
||||
}
|
||||
if (SDL_strncmp(name, "Nintendo ", 9) == 0 && SDL_strstr(name, " IMU") != NULL) {
|
||||
// Don't treat the Nintendo IMU as a separate gamepad
|
||||
return true;
|
||||
}
|
||||
if (SDL_endswith(name, " Accelerometer") ||
|
||||
SDL_endswith(name, " IR") ||
|
||||
SDL_endswith(name, " Motion Plus") ||
|
||||
SDL_endswith(name, " Nunchuk")) {
|
||||
// Don't treat the Wii extension controls as a separate gamepad
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
int i;
|
||||
for (i = 0; i < SDL_arraysize(SDL_gamepad_blacklist_words); i++) {
|
||||
const struct SDL_GamepadBlacklistWords *blacklist_word = &SDL_gamepad_blacklist_words[i];
|
||||
|
||||
if (name && SDL_strcmp(name, "uinput-fpc") == 0) {
|
||||
// The Google Pixel fingerprint sensor reports itself as a joystick
|
||||
return true;
|
||||
switch (blacklist_word->pos) {
|
||||
case GAMEPAD_BLACKLIST_BEGIN:
|
||||
if (SDL_startswith(name, blacklist_word->str)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case GAMEPAD_BLACKLIST_END:
|
||||
if (SDL_endswith(name, blacklist_word->str)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case GAMEPAD_BLACKLIST_ANYWHERE:
|
||||
if (SDL_strstr(name, blacklist_word->str) != NULL) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SDL_PLATFORM_WIN32
|
||||
|
||||
@@ -215,7 +215,7 @@ static const char *s_GamepadMappings[] = {
|
||||
"03000000362800000100000000000000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,x:b1,y:b2,",
|
||||
"03000000782300000a10000000000000,Onlive Wireless Controller,a:b15,b:b14,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b11,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b13,y:b12,",
|
||||
"030000006b14000001a1000000000000,Orange Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,",
|
||||
"0300000009120000072f000000000000,OrangeFox86 DreamPicoPort,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:-a2,leftx:a0,lefty:a1,rightx:a3,righty:a4,righttrigger:-a5,start:b11,x:b3,y:b4,",
|
||||
"0300000009120000072f000000000000,OrangeFox86 DreamPicoPort,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:-a2,leftx:a0,lefty:a1,righttrigger:-a5,rightx:a3,righty:a4,start:b11,x:b3,y:b4,",
|
||||
"03000000120c0000f60e000000000000,P4 Wired Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,",
|
||||
"030000006f0e00000901000000000000,PDP Versus Fighting Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
|
||||
"03000000632500002306000000000000,PS Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
||||
@@ -339,6 +339,7 @@ static const char *s_GamepadMappings[] = {
|
||||
"03000000172700004431000000000000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a7,rightx:a2,righty:a5,start:b11,x:b3,y:b4,",
|
||||
"03000000c0160000e105000000000000,Xin-Mo Dual Arcade,crc:2246,a:b1,b:b2,back:b9,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b4,righttrigger:b5,start:b8,x:b0,y:b3,", /* Ultimate Atari Fight Stick */
|
||||
"03000000790000004f18000000000000,ZD-T Android,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,",
|
||||
"03000000073500000400000000000000,ZENAIM ARCADE CONTROLLER,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,",
|
||||
"03000000120c0000101e000000000000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
|
||||
"03000000d81d00000f00000000000000,iBUFFALO BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,",
|
||||
"03000000d81d00001000000000000000,iBUFFALO BSGP1204P Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,",
|
||||
@@ -416,12 +417,13 @@ static const char *s_GamepadMappings[] = {
|
||||
"03000000790000004418000000010000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,",
|
||||
"0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,",
|
||||
"03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,",
|
||||
"03000000853200008906000000010000,NACON Revolution X Unlimited,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
||||
"030000001008000001e5000006010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,",
|
||||
"03000000550900001472000025050000,NVIDIA Controller v01.04,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,",
|
||||
"030000004b120000014d000000010000,NYKO AIRFLO EX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,",
|
||||
"030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
|
||||
"050000007e05000009200000ff070000,Nintendo Switch Pro Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
"0300000009120000072f000000010000,OrangeFox86 DreamPicoPort,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a2,leftx:a0,lefty:a1,rightx:a3,righty:a4,righttrigger:a5,start:b11,x:b3,y:b4,",
|
||||
"0300000009120000072f000000010000,OrangeFox86 DreamPicoPort,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a2,leftx:a0,lefty:a1,righttrigger:a5,rightx:a3,righty:a4,start:b11,x:b3,y:b4,",
|
||||
"030000006f0e00000901000002010000,PDP Versus Fighting Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
|
||||
"030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,",
|
||||
"030000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,",
|
||||
@@ -480,6 +482,7 @@ static const char *s_GamepadMappings[] = {
|
||||
"030000005e040000fd02000003090000,Xbox Wireless Controller,a:b0,b:b1,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
||||
"03000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,",
|
||||
"03000000c0160000e105000000040000,Xin-Mo Dual Arcade,crc:82d5,a:b2,b:b4,back:b18,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,rightshoulder:b8,righttrigger:b10,start:b16,x:b0,y:b6,", /* Ultimate Atari Fight Stick */
|
||||
"03000000073500000400000000010000,ZENAIM ARCADE CONTROLLER,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,",
|
||||
"03000000120c0000100e000000010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
|
||||
"03000000120c0000101e000000010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
|
||||
"03000000830500006020000000010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
@@ -501,6 +504,7 @@ static const char *s_GamepadMappings[] = {
|
||||
"06000000c82d00000020000006010000,8BitDo Pro 2 Wired Controller for Xbox,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
|
||||
"03000000c82d00000660000011010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
"05000000c82d00000660000000010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
"03000000c82d00000960000011010000,8BitDo Pro 3,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b17,paddle2:b16,paddle3:b2,paddle4:b5,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
"05000000c82d00000061000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
"05000000102800000900000000010000,8BitDo SFC30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
"05000000c82d00003028000000010000,8BitDo SFC30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
@@ -794,8 +798,10 @@ static const char *s_GamepadMappings[] = {
|
||||
"050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
|
||||
"05000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,",
|
||||
"03000000c0160000e105000010010000,Xin-Mo Dual Arcade,crc:82d5,a:b1,b:b2,back:b9,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b4,righttrigger:b5,start:b8,x:b0,y:b3,", /* Ultimate Atari Fight Stick */
|
||||
"03000000073500000400000011010000,ZENAIM ARCADE CONTROLLER,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,",
|
||||
"03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
|
||||
"03000000120c0000101e000011010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
|
||||
"03000000120c0000182e000011010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
|
||||
"03000000666600006706000000010000,boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,",
|
||||
"03000000830500006020000010010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
|
||||
"050000006964726f69643a636f6e0000,idroid:con,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
|
||||
|
||||
@@ -277,7 +277,10 @@ static Uint32 initial_blacklist_devices[] = {
|
||||
MAKE_VIDPID(0x1532, 0x0282), // Razer Huntsman Mini Analog, non-functional DInput device
|
||||
MAKE_VIDPID(0x26ce, 0x01a2), // ASRock LED Controller
|
||||
MAKE_VIDPID(0x20d6, 0x0002), // PowerA Enhanced Wireless Controller for Nintendo Switch (charging port only)
|
||||
MAKE_VIDPID(0x31e3, 0x1310), // Wooting 60HE (ARM)
|
||||
MAKE_VIDPID(0x3297, 0x1969), // Moonlander MK1 Keyboard
|
||||
MAKE_VIDPID(0x3434, 0x0211), // Keychron K1 Pro System Control
|
||||
MAKE_VIDPID(0x04f2, 0xa13c), // HP Deluxe Webcam KQ246AA
|
||||
};
|
||||
static SDL_vidpid_list blacklist_devices = {
|
||||
SDL_HINT_JOYSTICK_BLACKLIST_DEVICES, 0, 0, NULL,
|
||||
@@ -2143,6 +2146,7 @@ void SDL_PrivateJoystickAdded(SDL_JoystickID instance_id)
|
||||
SDL_JoystickDriver *driver;
|
||||
int device_index;
|
||||
int player_index = -1;
|
||||
bool is_gamepad;
|
||||
|
||||
SDL_AssertJoysticksLocked();
|
||||
|
||||
@@ -2177,9 +2181,12 @@ void SDL_PrivateJoystickAdded(SDL_JoystickID instance_id)
|
||||
}
|
||||
}
|
||||
|
||||
// This might create an automatic gamepad mapping, so wait to send the event
|
||||
is_gamepad = SDL_IsGamepad(instance_id);
|
||||
|
||||
SDL_joystick_being_added = false;
|
||||
|
||||
if (SDL_IsGamepad(instance_id)) {
|
||||
if (is_gamepad) {
|
||||
SDL_PrivateGamepadAdded(instance_id);
|
||||
}
|
||||
}
|
||||
@@ -2495,7 +2502,7 @@ void SDL_UpdateJoysticks(void)
|
||||
Uint64 now;
|
||||
SDL_Joystick *joystick;
|
||||
|
||||
if (!SDL_WasInit(SDL_INIT_JOYSTICK)) {
|
||||
if (!SDL_joysticks_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -328,6 +328,10 @@ void Android_AddJoystick(int device_id, const char *name, const char *desc, int
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (SDL_ShouldIgnoreJoystick(vendor_id, product_id, 0, name)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_JOYSTICK
|
||||
SDL_Log("Joystick: %s, descriptor %s, vendor = 0x%.4x, product = 0x%.4x, %d axes, %d hats", name, desc, vendor_id, product_id, naxes, nhats);
|
||||
#endif
|
||||
|
||||
@@ -300,8 +300,14 @@ static bool IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle
|
||||
* struct, and ARC doesn't work with structs. */
|
||||
device->controller = (__bridge GCController *)CFBridgingRetain(controller);
|
||||
|
||||
if (controller.vendorName) {
|
||||
name = controller.vendorName.UTF8String;
|
||||
if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) {
|
||||
if (controller.productCategory) {
|
||||
name = controller.productCategory.UTF8String;
|
||||
}
|
||||
} else {
|
||||
if (controller.vendorName) {
|
||||
name = controller.vendorName.UTF8String;
|
||||
}
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
static const ControllerDescription_t arrControllers[] = {
|
||||
{ MAKE_CONTROLLER_ID( 0x0079, 0x181a ), k_eControllerType_PS3Controller, NULL }, // Venom Arcade Stick
|
||||
{ MAKE_CONTROLLER_ID( 0x0079, 0x1844 ), k_eControllerType_PS3Controller, NULL }, // From SDL
|
||||
{ MAKE_CONTROLLER_ID( 0x044f, 0xb315 ), k_eControllerType_PS3Controller, NULL }, // Firestorm Dual Analog 3
|
||||
{ MAKE_CONTROLLER_ID( 0x044f, 0xd007 ), k_eControllerType_PS3Controller, NULL }, // Thrustmaster wireless 3-1
|
||||
{ MAKE_CONTROLLER_ID( 0x046d, 0xcad1 ), k_eControllerType_PS3Controller, NULL }, // Logitech Chillstream
|
||||
@@ -96,6 +95,7 @@ static const ControllerDescription_t arrControllers[] = {
|
||||
{ MAKE_CONTROLLER_ID( 0x0c12, 0x0ef6 ), k_eControllerType_PS4Controller, NULL }, // Hitbox Arcade Stick
|
||||
{ MAKE_CONTROLLER_ID( 0x0c12, 0x1cf6 ), k_eControllerType_PS4Controller, NULL }, // EMIO PS4 Elite Controller
|
||||
{ MAKE_CONTROLLER_ID( 0x0c12, 0x1e10 ), k_eControllerType_PS4Controller, NULL }, // P4 Wired Gamepad generic knock off - lightbar but not trackpad or gyro
|
||||
{ MAKE_CONTROLLER_ID( 0x0c12, 0x2e18 ), k_eControllerType_PS4Controller, NULL }, // ZEROPLUS P4 Wired Gamepad
|
||||
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0203 ), k_eControllerType_PS4Controller, NULL }, // Victrix Pro FS (PS4 peripheral but no trackpad/lightbar)
|
||||
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0207 ), k_eControllerType_PS4Controller, NULL }, // Victrix Pro FS V2 w/ Touchpad for PS4
|
||||
{ MAKE_CONTROLLER_ID( 0x0e6f, 0x020a ), k_eControllerType_PS4Controller, NULL }, // Victrix Pro FS PS4/PS5 (PS4 mode)
|
||||
@@ -435,7 +435,8 @@ static const ControllerDescription_t arrControllers[] = {
|
||||
{ MAKE_CONTROLLER_ID( 0x24c6, 0x592a ), k_eControllerType_XBoxOneController, NULL }, // BDA XB1 Spectra Pro
|
||||
{ MAKE_CONTROLLER_ID( 0x24c6, 0x791a ), k_eControllerType_XBoxOneController, NULL }, // PowerA Fusion Fight Pad
|
||||
{ MAKE_CONTROLLER_ID( 0x2dc8, 0x2002 ), k_eControllerType_XBoxOneController, NULL }, // 8BitDo Ultimate Wired Controller for Xbox
|
||||
{ MAKE_CONTROLLER_ID( 0x2dc8, 0x3106 ), k_eControllerType_XBoxOneController, NULL }, // 8Bitdo Ultimate Wired Controller. Windows, Android, Switch.
|
||||
{ MAKE_CONTROLLER_ID( 0x2dc8, 0x3106 ), k_eControllerType_XBoxOneController, NULL }, // 8BitDo Ultimate Wired Controller. Windows, Android, Switch.
|
||||
{ MAKE_CONTROLLER_ID( 0x2dc8, 0x310a ), k_eControllerType_XBoxOneController, NULL }, // 8BitDo Ultimate 2C Wireless Controller
|
||||
{ MAKE_CONTROLLER_ID( 0x2e24, 0x0652 ), k_eControllerType_XBoxOneController, NULL }, // Hyperkin Duke
|
||||
{ MAKE_CONTROLLER_ID( 0x2e24, 0x1618 ), k_eControllerType_XBoxOneController, NULL }, // Hyperkin Duke
|
||||
{ MAKE_CONTROLLER_ID( 0x2e24, 0x1688 ), k_eControllerType_XBoxOneController, NULL }, // Hyperkin X91
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "SDL_iokitjoystick_c.h"
|
||||
#include "../hidapi/SDL_hidapijoystick_c.h"
|
||||
#include "../../haptic/darwin/SDL_syshaptic_c.h" // For haptic hot plugging
|
||||
#include "../usb_ids.h"
|
||||
|
||||
#define SDL_JOYSTICK_RUNLOOP_MODE CFSTR("SDLJoystick")
|
||||
|
||||
@@ -213,6 +214,29 @@ static bool GetHIDScaledCalibratedState(recDevice *pDevice, recElement *pElement
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool GetHIDScaledCalibratedState_NACON_Revolution_X_Unlimited(recDevice *pDevice, recElement *pElement, SInt32 min, SInt32 max, SInt32 *pValue)
|
||||
{
|
||||
if (pElement->minReport == 0 && pElement->maxReport == 255) {
|
||||
return GetHIDScaledCalibratedState(pDevice, pElement, min, max, pValue);
|
||||
}
|
||||
|
||||
// This device thumbstick axes have an unusual axis range that
|
||||
// doesn't work with GetHIDScaledCalibratedState() above.
|
||||
//
|
||||
// See https://github.com/libsdl-org/SDL/issues/13143 for details
|
||||
if (GetHIDElementState(pDevice, pElement, pValue)) {
|
||||
if (*pValue >= 0) {
|
||||
// Negative axis values range from 32767 (at rest) to 0 (minimum)
|
||||
*pValue = -32767 + *pValue;
|
||||
} else if (*pValue < 0) {
|
||||
// Positive axis values range from -32768 (at rest) to 0 (maximum)
|
||||
*pValue = 32768 + *pValue;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void JoystickDeviceWasRemovedCallback(void *ctx, IOReturn result, void *sender)
|
||||
{
|
||||
recDevice *device = (recDevice *)ctx;
|
||||
@@ -506,6 +530,11 @@ static bool GetDeviceInfo(IOHIDDeviceRef hidDevice, recDevice *pDevice)
|
||||
pDevice->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_USB, (Uint16)vendor, (Uint16)product, (Uint16)version, manufacturer_string, product_string, 0, 0);
|
||||
pDevice->steam_virtual_gamepad_slot = GetSteamVirtualGamepadSlot((Uint16)vendor, (Uint16)product, product_string);
|
||||
|
||||
if (vendor == USB_VENDOR_NACON_ALT &&
|
||||
product == USB_PRODUCT_NACON_REVOLUTION_X_UNLIMITED_BT) {
|
||||
pDevice->nacon_revolution_x_unlimited = true;
|
||||
}
|
||||
|
||||
array = IOHIDDeviceCopyMatchingElements(hidDevice, NULL, kIOHIDOptionsTypeNone);
|
||||
if (array) {
|
||||
AddHIDElements(array, pDevice);
|
||||
@@ -957,7 +986,11 @@ static void DARWIN_JoystickUpdate(SDL_Joystick *joystick)
|
||||
i = 0;
|
||||
|
||||
while (element) {
|
||||
goodRead = GetHIDScaledCalibratedState(device, element, -32768, 32767, &value);
|
||||
if (device->nacon_revolution_x_unlimited) {
|
||||
goodRead = GetHIDScaledCalibratedState_NACON_Revolution_X_Unlimited(device, element, -32768, 32767, &value);
|
||||
} else {
|
||||
goodRead = GetHIDScaledCalibratedState(device, element, -32768, 32767, &value);
|
||||
}
|
||||
if (goodRead) {
|
||||
SDL_SendJoystickAxis(timestamp, joystick, i, value);
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ struct joystick_hwdata
|
||||
int instance_id;
|
||||
SDL_GUID guid;
|
||||
int steam_virtual_gamepad_slot;
|
||||
bool nacon_revolution_x_unlimited;
|
||||
|
||||
struct joystick_hwdata *pNext; // next device
|
||||
};
|
||||
|
||||
@@ -305,6 +305,7 @@ static SDL_JoystickID EMSCRIPTEN_JoystickGetDeviceInstanceID(int device_index)
|
||||
static bool EMSCRIPTEN_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
||||
{
|
||||
SDL_joylist_item *item = JoystickByDeviceIndex(device_index);
|
||||
bool rumble_available = false;
|
||||
|
||||
if (!item) {
|
||||
return SDL_SetError("No such device");
|
||||
@@ -323,6 +324,22 @@ static bool EMSCRIPTEN_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
||||
joystick->nbuttons = item->nbuttons;
|
||||
joystick->naxes = item->naxes;
|
||||
|
||||
rumble_available = EM_ASM_INT({
|
||||
let gamepads = navigator['getGamepads']();
|
||||
if (!gamepads) {
|
||||
return 0;
|
||||
}
|
||||
let gamepad = gamepads[$0];
|
||||
if (!gamepad || !gamepad['vibrationActuator']) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}, item->index);
|
||||
|
||||
if (rumble_available) {
|
||||
SDL_SetBooleanProperty(SDL_GetJoystickProperties(joystick), SDL_PROP_JOYSTICK_CAP_RUMBLE_BOOLEAN, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -390,7 +407,29 @@ static SDL_GUID EMSCRIPTEN_JoystickGetDeviceGUID(int device_index)
|
||||
|
||||
static bool EMSCRIPTEN_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
SDL_joylist_item *item = (SDL_joylist_item *)joystick->hwdata;
|
||||
|
||||
// clang-format off
|
||||
bool result = EM_ASM_INT({
|
||||
let gamepads = navigator['getGamepads']();
|
||||
if (!gamepads) {
|
||||
return 0;
|
||||
}
|
||||
let gamepad = gamepads[$0];
|
||||
if (!gamepad || !gamepad['vibrationActuator']) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
gamepad['vibrationActuator']['playEffect']('dual-rumble', {
|
||||
'startDelay': 0,
|
||||
'duration': 3000,
|
||||
'weakMagnitude': $1 / 0xFFFF,
|
||||
'strongMagnitude': $2 / 0xFFFF,
|
||||
});
|
||||
return 1;
|
||||
}, item->index, low_frequency_rumble, high_frequency_rumble);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool EMSCRIPTEN_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
|
||||
|
||||
@@ -31,7 +31,9 @@
|
||||
#ifdef SDL_JOYSTICK_HIDAPI_GAMECUBE
|
||||
|
||||
// Define this if you want to log all packets from the controller
|
||||
// #define DEBUG_GAMECUBE_PROTOCOL
|
||||
#if 0
|
||||
#define DEBUG_GAMECUBE_PROTOCOL
|
||||
#endif
|
||||
|
||||
#define MAX_CONTROLLERS 4
|
||||
|
||||
@@ -119,22 +121,15 @@ static bool HIDAPI_DriverGameCube_InitDevice(SDL_HIDAPI_Device *device)
|
||||
}
|
||||
device->context = ctx;
|
||||
|
||||
ctx->joysticks[0] = 0;
|
||||
ctx->joysticks[1] = 0;
|
||||
ctx->joysticks[2] = 0;
|
||||
ctx->joysticks[3] = 0;
|
||||
ctx->rumble[0] = rumbleMagic;
|
||||
ctx->useRumbleBrake = false;
|
||||
|
||||
if (device->vendor_id != USB_VENDOR_NINTENDO) {
|
||||
ctx->pc_mode = true;
|
||||
}
|
||||
|
||||
if (ctx->pc_mode) {
|
||||
for (i = 0; i < MAX_CONTROLLERS; ++i) {
|
||||
ResetAxisRange(ctx, i);
|
||||
HIDAPI_JoystickConnected(device, &ctx->joysticks[i]);
|
||||
}
|
||||
ResetAxisRange(ctx, 0);
|
||||
HIDAPI_JoystickConnected(device, &ctx->joysticks[0]);
|
||||
} else {
|
||||
// This is all that's needed to initialize the device. Really!
|
||||
if (SDL_hid_write(device->dev, &initMagic, sizeof(initMagic)) != sizeof(initMagic)) {
|
||||
@@ -204,69 +199,61 @@ static void HIDAPI_DriverGameCube_SetDevicePlayerIndex(SDL_HIDAPI_Device *device
|
||||
{
|
||||
}
|
||||
|
||||
static void HIDAPI_DriverGameCube_HandleJoystickPacket(SDL_HIDAPI_Device *device, SDL_DriverGameCube_Context *ctx, const Uint8 *packet, int size)
|
||||
static void HIDAPI_DriverGameCube_HandleJoystickPacket(SDL_HIDAPI_Device *device, SDL_DriverGameCube_Context *ctx, const Uint8 *packet, bool invert_c_stick)
|
||||
{
|
||||
SDL_Joystick *joystick;
|
||||
Uint8 i, v;
|
||||
const Uint8 i = 0; // We have a separate context for each connected controller in PC mode, just use the first index
|
||||
Uint8 v;
|
||||
Sint16 axis_value;
|
||||
Uint64 timestamp = SDL_GetTicksNS();
|
||||
|
||||
if (size != 10) {
|
||||
return; // How do we handle this packet?
|
||||
}
|
||||
|
||||
i = packet[0] - 1;
|
||||
if (i >= MAX_CONTROLLERS) {
|
||||
return; // How do we handle this packet?
|
||||
}
|
||||
|
||||
joystick = SDL_GetJoystickFromID(ctx->joysticks[i]);
|
||||
if (!joystick) {
|
||||
// Hasn't been opened yet, skip
|
||||
return;
|
||||
}
|
||||
|
||||
#define READ_BUTTON(off, flag, button) \
|
||||
SDL_SendJoystickButton( \
|
||||
timestamp, \
|
||||
joystick, \
|
||||
button, \
|
||||
#define READ_BUTTON(off, flag, button) \
|
||||
SDL_SendJoystickButton( \
|
||||
timestamp, \
|
||||
joystick, \
|
||||
button, \
|
||||
((packet[off] & flag) != 0));
|
||||
READ_BUTTON(1, 0x02, 0) // A
|
||||
READ_BUTTON(1, 0x04, 1) // B
|
||||
READ_BUTTON(1, 0x08, 3) // Y
|
||||
READ_BUTTON(1, 0x01, 2) // X
|
||||
READ_BUTTON(2, 0x80, 4) // DPAD_LEFT
|
||||
READ_BUTTON(2, 0x20, 5) // DPAD_RIGHT
|
||||
READ_BUTTON(2, 0x40, 6) // DPAD_DOWN
|
||||
READ_BUTTON(2, 0x10, 7) // DPAD_UP
|
||||
READ_BUTTON(2, 0x02, 8) // START
|
||||
READ_BUTTON(1, 0x80, 9) // RIGHTSHOULDER
|
||||
READ_BUTTON(0, 0x02, 0) // A
|
||||
READ_BUTTON(0, 0x04, 1) // B
|
||||
READ_BUTTON(0, 0x08, 3) // Y
|
||||
READ_BUTTON(0, 0x01, 2) // X
|
||||
READ_BUTTON(1, 0x80, 4) // DPAD_LEFT
|
||||
READ_BUTTON(1, 0x20, 5) // DPAD_RIGHT
|
||||
READ_BUTTON(1, 0x40, 6) // DPAD_DOWN
|
||||
READ_BUTTON(1, 0x10, 7) // DPAD_UP
|
||||
READ_BUTTON(1, 0x02, 8) // START
|
||||
READ_BUTTON(0, 0x80, 9) // RIGHTSHOULDER
|
||||
/* These two buttons are for the bottoms of the analog triggers.
|
||||
* More than likely, you're going to want to read the axes instead!
|
||||
* -flibit
|
||||
*/
|
||||
READ_BUTTON(1, 0x20, 10) // TRIGGERRIGHT
|
||||
READ_BUTTON(1, 0x10, 11) // TRIGGERLEFT
|
||||
READ_BUTTON(0, 0x20, 10) // TRIGGERRIGHT
|
||||
READ_BUTTON(0, 0x10, 11) // TRIGGERLEFT
|
||||
#undef READ_BUTTON
|
||||
|
||||
#define READ_AXIS(off, axis, invert) \
|
||||
v = invert ? (0xff - packet[off]) : packet[off]; \
|
||||
if (v < ctx->min_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis]) \
|
||||
ctx->min_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis] = v; \
|
||||
if (v > ctx->max_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis]) \
|
||||
ctx->max_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis] = v; \
|
||||
#define READ_AXIS(off, axis, invert) \
|
||||
v = (invert) ? (0xff - packet[off]) : packet[off]; \
|
||||
if (v < ctx->min_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis]) \
|
||||
ctx->min_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis] = v; \
|
||||
if (v > ctx->max_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis]) \
|
||||
ctx->max_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis] = v; \
|
||||
axis_value = (Sint16)HIDAPI_RemapVal(v, ctx->min_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis], ctx->max_axis[i * SDL_GAMEPAD_AXIS_COUNT + axis], SDL_MIN_SINT16, SDL_MAX_SINT16); \
|
||||
SDL_SendJoystickAxis( \
|
||||
timestamp, \
|
||||
joystick, \
|
||||
SDL_SendJoystickAxis( \
|
||||
timestamp, \
|
||||
joystick, \
|
||||
axis, axis_value);
|
||||
READ_AXIS(3, SDL_GAMEPAD_AXIS_LEFTX, 0)
|
||||
READ_AXIS(4, SDL_GAMEPAD_AXIS_LEFTY, 1)
|
||||
READ_AXIS(6, SDL_GAMEPAD_AXIS_RIGHTX, 0)
|
||||
READ_AXIS(5, SDL_GAMEPAD_AXIS_RIGHTY, 1)
|
||||
READ_AXIS(7, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, 0)
|
||||
READ_AXIS(8, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, 0)
|
||||
READ_AXIS(2, SDL_GAMEPAD_AXIS_LEFTX, 0)
|
||||
READ_AXIS(3, SDL_GAMEPAD_AXIS_LEFTY, 1)
|
||||
READ_AXIS(5, SDL_GAMEPAD_AXIS_RIGHTX, invert_c_stick ? 1 : 0)
|
||||
READ_AXIS(4, SDL_GAMEPAD_AXIS_RIGHTY, invert_c_stick ? 0 : 1)
|
||||
READ_AXIS(6, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, 0)
|
||||
READ_AXIS(7, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, 0)
|
||||
#undef READ_AXIS
|
||||
}
|
||||
|
||||
@@ -365,7 +352,18 @@ static bool HIDAPI_DriverGameCube_UpdateDevice(SDL_HIDAPI_Device *device)
|
||||
HIDAPI_DumpPacket("Nintendo GameCube packet: size = %d", packet, size);
|
||||
#endif
|
||||
if (ctx->pc_mode) {
|
||||
HIDAPI_DriverGameCube_HandleJoystickPacket(device, ctx, packet, size);
|
||||
if (size == 10) {
|
||||
// This is the older firmware
|
||||
// The first byte is the index of the connected controller
|
||||
// The C stick has an inverted value range compared to the left stick
|
||||
HIDAPI_DriverGameCube_HandleJoystickPacket(device, ctx, &packet[1], true);
|
||||
} else if (size == 9) {
|
||||
// This is the newer firmware (version 0x7)
|
||||
// The C stick has the same value range compared to the left stick
|
||||
HIDAPI_DriverGameCube_HandleJoystickPacket(device, ctx, packet, false);
|
||||
} else {
|
||||
// How do we handle this packet?
|
||||
}
|
||||
} else {
|
||||
HIDAPI_DriverGameCube_HandleNintendoPacket(device, ctx, packet, size);
|
||||
}
|
||||
|
||||
@@ -1003,8 +1003,8 @@ static bool HIDAPI_DriverPS4_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device
|
||||
|
||||
static void HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS4_Context *ctx, PS4StatePacket_t *packet, int size)
|
||||
{
|
||||
static const float TOUCHPAD_SCALEX = 1.0f / 1920;
|
||||
static const float TOUCHPAD_SCALEY = 1.0f / 920; // This is noted as being 944 resolution, but 920 feels better
|
||||
static const float TOUCHPAD_SCALEX = 5.20833333e-4f; // 1.0f / 1920
|
||||
static const float TOUCHPAD_SCALEY = 1.08695652e-3f; // 1.0f / 920 // This is noted as being 944 resolution, but 920 feels better
|
||||
Sint16 axis;
|
||||
bool touchpad_down;
|
||||
int touchpad_x, touchpad_y;
|
||||
|
||||
@@ -251,6 +251,7 @@ typedef struct
|
||||
Uint64 last_packet;
|
||||
int player_index;
|
||||
bool player_lights;
|
||||
bool enhanced_rumble;
|
||||
Uint8 rumble_left;
|
||||
Uint8 rumble_right;
|
||||
bool color_set;
|
||||
@@ -432,6 +433,14 @@ static bool HIDAPI_DriverPS5_InitDevice(SDL_HIDAPI_Device *device)
|
||||
}
|
||||
}
|
||||
|
||||
if (device->vendor_id == USB_VENDOR_SONY) {
|
||||
if (device->product_id == USB_PRODUCT_SONY_DS5_EDGE ||
|
||||
ctx->firmware_version == 0 || // Assume that it's updated firmware over Bluetooth
|
||||
ctx->firmware_version >= 0x0224) {
|
||||
ctx->enhanced_rumble = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the device capabilities
|
||||
if (device->vendor_id == USB_VENDOR_SONY) {
|
||||
ctx->sensors_supported = true;
|
||||
@@ -684,17 +693,17 @@ static bool HIDAPI_DriverPS5_UpdateEffects(SDL_DriverPS5_Context *ctx, int effec
|
||||
|
||||
if (ctx->vibration_supported) {
|
||||
if (ctx->rumble_left || ctx->rumble_right) {
|
||||
if (ctx->firmware_version < 0x0224) {
|
||||
if (ctx->enhanced_rumble) {
|
||||
effects.ucEnableBits3 |= 0x04; // Enable improved rumble emulation on 2.24 firmware and newer
|
||||
|
||||
effects.ucRumbleLeft = ctx->rumble_left;
|
||||
effects.ucRumbleRight = ctx->rumble_right;
|
||||
} else {
|
||||
effects.ucEnableBits1 |= 0x01; // Enable rumble emulation
|
||||
|
||||
// Shift to reduce effective rumble strength to match Xbox controllers
|
||||
effects.ucRumbleLeft = ctx->rumble_left >> 1;
|
||||
effects.ucRumbleRight = ctx->rumble_right >> 1;
|
||||
} else {
|
||||
effects.ucEnableBits3 |= 0x04; // Enable improved rumble emulation on 2.24 firmware and newer
|
||||
|
||||
effects.ucRumbleLeft = ctx->rumble_left;
|
||||
effects.ucRumbleRight = ctx->rumble_right;
|
||||
}
|
||||
effects.ucEnableBits1 |= 0x02; // Disable audio haptics
|
||||
} else {
|
||||
@@ -812,14 +821,19 @@ static void HIDAPI_DriverPS5_SetEnhancedModeAvailable(SDL_DriverPS5_Context *ctx
|
||||
}
|
||||
|
||||
if (ctx->sensors_supported) {
|
||||
// Standard DualSense sensor update rate is 250 Hz over USB
|
||||
float update_rate = 250.0f;
|
||||
|
||||
if (ctx->device->is_bluetooth) {
|
||||
// Bluetooth sensor update rate appears to be 1000 Hz
|
||||
SDL_PrivateJoystickAddSensor(ctx->joystick, SDL_SENSOR_GYRO, 1000.0f);
|
||||
SDL_PrivateJoystickAddSensor(ctx->joystick, SDL_SENSOR_ACCEL, 1000.0f);
|
||||
} else {
|
||||
SDL_PrivateJoystickAddSensor(ctx->joystick, SDL_SENSOR_GYRO, 250.0f);
|
||||
SDL_PrivateJoystickAddSensor(ctx->joystick, SDL_SENSOR_ACCEL, 250.0f);
|
||||
update_rate = 1000.0f;
|
||||
} else if (SDL_IsJoystickDualSenseEdge(ctx->device->vendor_id, ctx->device->product_id)) {
|
||||
// DualSense Edge sensor update rate is 1000 Hz over USB
|
||||
update_rate = 1000.0f;
|
||||
}
|
||||
|
||||
SDL_PrivateJoystickAddSensor(ctx->joystick, SDL_SENSOR_GYRO, update_rate);
|
||||
SDL_PrivateJoystickAddSensor(ctx->joystick, SDL_SENSOR_ACCEL, update_rate);
|
||||
}
|
||||
|
||||
ctx->report_battery = true;
|
||||
@@ -1033,6 +1047,9 @@ static bool HIDAPI_DriverPS5_InternalSendJoystickEffect(SDL_DriverPS5_Context *c
|
||||
if (!ctx->enhanced_mode) {
|
||||
if (application_usage) {
|
||||
HIDAPI_DriverPS5_UpdateEnhancedModeOnApplicationUsage(ctx);
|
||||
|
||||
// Wait briefly before sending additional effects
|
||||
SDL_Delay(10);
|
||||
}
|
||||
|
||||
if (!ctx->enhanced_mode) {
|
||||
@@ -1355,8 +1372,8 @@ static void HIDAPI_DriverPS5_HandleStatePacketCommon(SDL_Joystick *joystick, SDL
|
||||
|
||||
static void HIDAPI_DriverPS5_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS5_Context *ctx, PS5StatePacket_t *packet, Uint64 timestamp)
|
||||
{
|
||||
static const float TOUCHPAD_SCALEX = 1.0f / 1920;
|
||||
static const float TOUCHPAD_SCALEY = 1.0f / 1070;
|
||||
static const float TOUCHPAD_SCALEX = 5.20833333e-4f; // 1.0f / 1920
|
||||
static const float TOUCHPAD_SCALEY = 9.34579439e-4f; // 1.0f / 1070
|
||||
bool touchpad_down;
|
||||
int touchpad_x, touchpad_y;
|
||||
|
||||
@@ -1406,8 +1423,8 @@ static void HIDAPI_DriverPS5_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_d
|
||||
|
||||
static void HIDAPI_DriverPS5_HandleStatePacketAlt(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS5_Context *ctx, PS5StatePacketAlt_t *packet, Uint64 timestamp)
|
||||
{
|
||||
static const float TOUCHPAD_SCALEX = 1.0f / 1920;
|
||||
static const float TOUCHPAD_SCALEY = 1.0f / 1070;
|
||||
static const float TOUCHPAD_SCALEX = 5.20833333e-4f; // 1.0f / 1920
|
||||
static const float TOUCHPAD_SCALEY = 9.34579439e-4f; // 1.0f / 1070
|
||||
bool touchpad_down;
|
||||
int touchpad_x, touchpad_y;
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#ifdef SDL_THREAD_SAFETY_ANALYSIS
|
||||
extern SDL_Mutex *SDL_HIDAPI_rumble_lock;
|
||||
#endif
|
||||
bool SDL_HIDAPI_LockRumble(void) SDL_TRY_ACQUIRE(0, SDL_HIDAPI_rumble_lock);
|
||||
bool SDL_HIDAPI_LockRumble(void) SDL_TRY_ACQUIRE(true, SDL_HIDAPI_rumble_lock);
|
||||
bool SDL_HIDAPI_GetPendingRumbleLocked(SDL_HIDAPI_Device *device, Uint8 **data, int **size, int *maximum_size);
|
||||
int SDL_HIDAPI_SendRumbleAndUnlock(SDL_HIDAPI_Device *device, const Uint8 *data, int size) SDL_RELEASE(SDL_HIDAPI_rumble_lock);
|
||||
typedef void (*SDL_HIDAPI_RumbleSentCallback)(void *userdata);
|
||||
|
||||
@@ -1038,6 +1038,11 @@ static bool HIDAPI_DriverSteam_IsSupportedDevice(SDL_HIDAPI_Device *device, cons
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!device) {
|
||||
// Might be supported by this driver, enumerate and find out
|
||||
return true;
|
||||
}
|
||||
|
||||
if (device->is_bluetooth) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -58,9 +58,7 @@
|
||||
#define SWITCH_GYRO_SCALE 14.2842f
|
||||
#define SWITCH_ACCEL_SCALE 4096.f
|
||||
|
||||
#define SWITCH_GYRO_SCALE_OFFSET 13371.0f
|
||||
#define SWITCH_GYRO_SCALE_MULT 936.0f
|
||||
#define SWITCH_ACCEL_SCALE_OFFSET 16384.0f
|
||||
#define SWITCH_ACCEL_SCALE_MULT 4.0f
|
||||
|
||||
enum
|
||||
@@ -930,13 +928,14 @@ static bool SetIMUEnabled(SDL_DriverSwitch_Context *ctx, bool enabled)
|
||||
|
||||
static bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx)
|
||||
{
|
||||
Uint8 *pLeftStickCal;
|
||||
Uint8 *pRightStickCal;
|
||||
Uint8 *pLeftStickCal = NULL;
|
||||
Uint8 *pRightStickCal = NULL;
|
||||
size_t stick, axis;
|
||||
SwitchSubcommandInputPacket_t *user_reply = NULL;
|
||||
SwitchSubcommandInputPacket_t *factory_reply = NULL;
|
||||
SwitchSPIOpData_t readUserParams;
|
||||
SwitchSPIOpData_t readFactoryParams;
|
||||
Uint8 userParamsReadSuccessCount = 0;
|
||||
|
||||
// Read User Calibration Info
|
||||
readUserParams.unAddress = k_unSPIStickUserCalibrationStartOffset;
|
||||
@@ -949,33 +948,46 @@ static bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx)
|
||||
readFactoryParams.unAddress = k_unSPIStickFactoryCalibrationStartOffset;
|
||||
readFactoryParams.ucLength = k_unSPIStickFactoryCalibrationLength;
|
||||
|
||||
const int MAX_ATTEMPTS = 3;
|
||||
for (int attempt = 0; ; ++attempt) {
|
||||
if (!WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readFactoryParams, sizeof(readFactoryParams), &factory_reply)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (factory_reply->stickFactoryCalibration.opData.unAddress == k_unSPIStickFactoryCalibrationStartOffset) {
|
||||
// We successfully read the calibration data
|
||||
break;
|
||||
}
|
||||
|
||||
if (attempt == MAX_ATTEMPTS) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Automatically select the user calibration if magic bytes are set
|
||||
if (user_reply && user_reply->stickUserCalibration.rgucLeftMagic[0] == 0xB2 && user_reply->stickUserCalibration.rgucLeftMagic[1] == 0xA1) {
|
||||
userParamsReadSuccessCount += 1;
|
||||
pLeftStickCal = user_reply->stickUserCalibration.rgucLeftCalibration;
|
||||
} else {
|
||||
pLeftStickCal = factory_reply->stickFactoryCalibration.rgucLeftCalibration;
|
||||
}
|
||||
|
||||
if (user_reply && user_reply->stickUserCalibration.rgucRightMagic[0] == 0xB2 && user_reply->stickUserCalibration.rgucRightMagic[1] == 0xA1) {
|
||||
userParamsReadSuccessCount += 1;
|
||||
pRightStickCal = user_reply->stickUserCalibration.rgucRightCalibration;
|
||||
} else {
|
||||
pRightStickCal = factory_reply->stickFactoryCalibration.rgucRightCalibration;
|
||||
}
|
||||
|
||||
// Only read the factory calibration info if we failed to receive the correct magic bytes
|
||||
if (userParamsReadSuccessCount < 2) {
|
||||
// Read Factory Calibration Info
|
||||
readFactoryParams.unAddress = k_unSPIStickFactoryCalibrationStartOffset;
|
||||
readFactoryParams.ucLength = k_unSPIStickFactoryCalibrationLength;
|
||||
|
||||
const int MAX_ATTEMPTS = 3;
|
||||
for (int attempt = 0;; ++attempt) {
|
||||
if (!WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readFactoryParams, sizeof(readFactoryParams), &factory_reply)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (factory_reply->stickFactoryCalibration.opData.unAddress == k_unSPIStickFactoryCalibrationStartOffset) {
|
||||
// We successfully read the calibration data
|
||||
pLeftStickCal = factory_reply->stickFactoryCalibration.rgucLeftCalibration;
|
||||
pRightStickCal = factory_reply->stickFactoryCalibration.rgucRightCalibration;
|
||||
break;
|
||||
}
|
||||
|
||||
if (attempt == MAX_ATTEMPTS) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we still don't have calibration data, return false
|
||||
if (pLeftStickCal == NULL || pRightStickCal == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Stick calibration values are 12-bits each and are packed by bit
|
||||
@@ -1044,6 +1056,8 @@ static bool LoadIMUCalibration(SDL_DriverSwitch_Context *ctx)
|
||||
if (WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readParams, sizeof(readParams), &reply)) {
|
||||
Uint8 *pIMUScale;
|
||||
Sint16 sAccelRawX, sAccelRawY, sAccelRawZ, sGyroRawX, sGyroRawY, sGyroRawZ;
|
||||
Sint16 sAccelSensCoeffX, sAccelSensCoeffY, sAccelSensCoeffZ;
|
||||
Sint16 sGyroSensCoeffX, sGyroSensCoeffY, sGyroSensCoeffZ;
|
||||
|
||||
// IMU scale gives us multipliers for converting raw values to real world values
|
||||
pIMUScale = reply->spiReadData.rgucReadData;
|
||||
@@ -1052,10 +1066,18 @@ static bool LoadIMUCalibration(SDL_DriverSwitch_Context *ctx)
|
||||
sAccelRawY = (pIMUScale[3] << 8) | pIMUScale[2];
|
||||
sAccelRawZ = (pIMUScale[5] << 8) | pIMUScale[4];
|
||||
|
||||
sAccelSensCoeffX = (pIMUScale[7] << 8) | pIMUScale[6];
|
||||
sAccelSensCoeffY = (pIMUScale[9] << 8) | pIMUScale[8];
|
||||
sAccelSensCoeffZ = (pIMUScale[11] << 8) | pIMUScale[10];
|
||||
|
||||
sGyroRawX = (pIMUScale[13] << 8) | pIMUScale[12];
|
||||
sGyroRawY = (pIMUScale[15] << 8) | pIMUScale[14];
|
||||
sGyroRawZ = (pIMUScale[17] << 8) | pIMUScale[16];
|
||||
|
||||
sGyroSensCoeffX = (pIMUScale[19] << 8) | pIMUScale[18];
|
||||
sGyroSensCoeffY = (pIMUScale[21] << 8) | pIMUScale[20];
|
||||
sGyroSensCoeffZ = (pIMUScale[23] << 8) | pIMUScale[22];
|
||||
|
||||
// Check for user calibration data. If it's present and set, it'll override the factory settings
|
||||
readParams.unAddress = k_unSPIIMUUserScaleStartOffset;
|
||||
readParams.ucLength = k_unSPIIMUUserScaleLength;
|
||||
@@ -1072,14 +1094,14 @@ static bool LoadIMUCalibration(SDL_DriverSwitch_Context *ctx)
|
||||
}
|
||||
|
||||
// Accelerometer scale
|
||||
ctx->m_IMUScaleData.fAccelScaleX = SWITCH_ACCEL_SCALE_MULT / (SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawX) * SDL_STANDARD_GRAVITY;
|
||||
ctx->m_IMUScaleData.fAccelScaleY = SWITCH_ACCEL_SCALE_MULT / (SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawY) * SDL_STANDARD_GRAVITY;
|
||||
ctx->m_IMUScaleData.fAccelScaleZ = SWITCH_ACCEL_SCALE_MULT / (SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawZ) * SDL_STANDARD_GRAVITY;
|
||||
ctx->m_IMUScaleData.fAccelScaleX = SWITCH_ACCEL_SCALE_MULT / ((float)sAccelSensCoeffX - (float)sAccelRawX) * SDL_STANDARD_GRAVITY;
|
||||
ctx->m_IMUScaleData.fAccelScaleY = SWITCH_ACCEL_SCALE_MULT / ((float)sAccelSensCoeffY - (float)sAccelRawY) * SDL_STANDARD_GRAVITY;
|
||||
ctx->m_IMUScaleData.fAccelScaleZ = SWITCH_ACCEL_SCALE_MULT / ((float)sAccelSensCoeffZ - (float)sAccelRawZ) * SDL_STANDARD_GRAVITY;
|
||||
|
||||
// Gyro scale
|
||||
ctx->m_IMUScaleData.fGyroScaleX = SWITCH_GYRO_SCALE_MULT / (SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawX) * SDL_PI_F / 180.0f;
|
||||
ctx->m_IMUScaleData.fGyroScaleY = SWITCH_GYRO_SCALE_MULT / (SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawY) * SDL_PI_F / 180.0f;
|
||||
ctx->m_IMUScaleData.fGyroScaleZ = SWITCH_GYRO_SCALE_MULT / (SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawZ) * SDL_PI_F / 180.0f;
|
||||
ctx->m_IMUScaleData.fGyroScaleX = SWITCH_GYRO_SCALE_MULT / ((float)sGyroSensCoeffX - (float)sGyroRawX) * SDL_PI_F / 180.0f;
|
||||
ctx->m_IMUScaleData.fGyroScaleY = SWITCH_GYRO_SCALE_MULT / ((float)sGyroSensCoeffY - (float)sGyroRawY) * SDL_PI_F / 180.0f;
|
||||
ctx->m_IMUScaleData.fGyroScaleZ = SWITCH_GYRO_SCALE_MULT / ((float)sGyroSensCoeffZ - (float)sGyroRawZ) * SDL_PI_F / 180.0f;
|
||||
|
||||
} else {
|
||||
// Use default values
|
||||
@@ -1101,14 +1123,17 @@ static Sint16 ApplyStickCalibration(SDL_DriverSwitch_Context *ctx, int nStick, i
|
||||
{
|
||||
sRawValue -= ctx->m_StickCalData[nStick].axis[nAxis].sCenter;
|
||||
|
||||
if (sRawValue > ctx->m_StickExtents[nStick].axis[nAxis].sMax) {
|
||||
ctx->m_StickExtents[nStick].axis[nAxis].sMax = sRawValue;
|
||||
if (sRawValue >= 0) {
|
||||
if (sRawValue > ctx->m_StickExtents[nStick].axis[nAxis].sMax) {
|
||||
ctx->m_StickExtents[nStick].axis[nAxis].sMax = sRawValue;
|
||||
}
|
||||
return (Sint16)HIDAPI_RemapVal(sRawValue, 0, ctx->m_StickExtents[nStick].axis[nAxis].sMax, 0, SDL_MAX_SINT16);
|
||||
} else {
|
||||
if (sRawValue < ctx->m_StickExtents[nStick].axis[nAxis].sMin) {
|
||||
ctx->m_StickExtents[nStick].axis[nAxis].sMin = sRawValue;
|
||||
}
|
||||
return (Sint16)HIDAPI_RemapVal(sRawValue, ctx->m_StickExtents[nStick].axis[nAxis].sMin, 0, SDL_MIN_SINT16, 0);
|
||||
}
|
||||
if (sRawValue < ctx->m_StickExtents[nStick].axis[nAxis].sMin) {
|
||||
ctx->m_StickExtents[nStick].axis[nAxis].sMin = sRawValue;
|
||||
}
|
||||
|
||||
return (Sint16)HIDAPI_RemapVal(sRawValue, ctx->m_StickExtents[nStick].axis[nAxis].sMin, ctx->m_StickExtents[nStick].axis[nAxis].sMax, SDL_MIN_SINT16, SDL_MAX_SINT16);
|
||||
}
|
||||
|
||||
static Sint16 ApplySimpleStickCalibration(SDL_DriverSwitch_Context *ctx, int nStick, int nAxis, Sint16 sRawValue)
|
||||
@@ -1118,14 +1143,17 @@ static Sint16 ApplySimpleStickCalibration(SDL_DriverSwitch_Context *ctx, int nSt
|
||||
|
||||
sRawValue -= usJoystickCenter;
|
||||
|
||||
if (sRawValue > ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax) {
|
||||
ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax = sRawValue;
|
||||
if (sRawValue >= 0) {
|
||||
if (sRawValue > ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax) {
|
||||
ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax = sRawValue;
|
||||
}
|
||||
return (Sint16)HIDAPI_RemapVal(sRawValue, 0, ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax, 0, SDL_MAX_SINT16);
|
||||
} else {
|
||||
if (sRawValue < ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin) {
|
||||
ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin = sRawValue;
|
||||
}
|
||||
return (Sint16)HIDAPI_RemapVal(sRawValue, ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin, 0, SDL_MIN_SINT16, 0);
|
||||
}
|
||||
if (sRawValue < ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin) {
|
||||
ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin = sRawValue;
|
||||
}
|
||||
|
||||
return (Sint16)HIDAPI_RemapVal(sRawValue, ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin, ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax, SDL_MIN_SINT16, SDL_MAX_SINT16);
|
||||
}
|
||||
|
||||
static Uint8 RemapButton(SDL_DriverSwitch_Context *ctx, Uint8 button)
|
||||
|
||||
@@ -84,6 +84,7 @@
|
||||
#define USB_PRODUCT_NACON_REVOLUTION_5_PRO_PS4_WIRED 0x0d17
|
||||
#define USB_PRODUCT_NACON_REVOLUTION_5_PRO_PS5_WIRELESS 0x0d18
|
||||
#define USB_PRODUCT_NACON_REVOLUTION_5_PRO_PS5_WIRED 0x0d19
|
||||
#define USB_PRODUCT_NACON_REVOLUTION_X_UNLIMITED_BT 0x0689
|
||||
#define USB_PRODUCT_NINTENDO_GAMECUBE_ADAPTER 0x0337
|
||||
#define USB_PRODUCT_NINTENDO_N64_CONTROLLER 0x2019
|
||||
#define USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER 0x201e
|
||||
|
||||
@@ -471,7 +471,7 @@ bool SDL_SendJoystickVirtualSensorDataInner(SDL_Joystick *joystick, SDL_SensorTy
|
||||
return false;
|
||||
}
|
||||
hwdata->sensor_events = sensor_events;
|
||||
hwdata->max_sensor_events = hwdata->max_sensor_events;
|
||||
hwdata->max_sensor_events = new_max_sensor_events;
|
||||
}
|
||||
|
||||
VirtualSensorEvent *event = &hwdata->sensor_events[hwdata->num_sensor_events++];
|
||||
|
||||
@@ -40,11 +40,7 @@
|
||||
#define CONVERT_MAGNITUDE(x) (((x)*10000) / 0x7FFF)
|
||||
|
||||
// external variables referenced.
|
||||
#ifdef SDL_VIDEO_DRIVER_WINDOWS
|
||||
extern HWND SDL_HelperWindow;
|
||||
#else
|
||||
static const HWND SDL_HelperWindow = NULL;
|
||||
#endif
|
||||
|
||||
// local variables
|
||||
static bool coinitialized = false;
|
||||
|
||||
@@ -69,6 +69,7 @@ typedef PCWSTR(WINAPI *WindowsGetStringRawBuffer_t)(HSTRING string, UINT32 *leng
|
||||
|
||||
static struct
|
||||
{
|
||||
bool ro_initialized;
|
||||
CoIncrementMTAUsage_t CoIncrementMTAUsage;
|
||||
RoGetActivationFactory_t RoGetActivationFactory;
|
||||
WindowsCreateStringReference_t WindowsCreateStringReference;
|
||||
@@ -585,13 +586,14 @@ static bool WGI_JoystickInit(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_WGI, true)) {
|
||||
if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_WGI, false)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (FAILED(WIN_RoInitialize())) {
|
||||
return SDL_SetError("RoInitialize() failed");
|
||||
}
|
||||
wgi.ro_initialized = true;
|
||||
|
||||
#define RESOLVE(x) wgi.x = (x##_t)WIN_LoadComBaseFunction(#x); if (!wgi.x) return WIN_SetError("GetProcAddress failed for " #x);
|
||||
RESOLVE(CoIncrementMTAUsage);
|
||||
@@ -1002,7 +1004,9 @@ static void WGI_JoystickQuit(void)
|
||||
__x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_Release(wgi.controller_statics);
|
||||
}
|
||||
|
||||
WIN_RoUninitialize();
|
||||
if (wgi.ro_initialized) {
|
||||
WIN_RoUninitialize();
|
||||
}
|
||||
|
||||
SDL_zero(wgi);
|
||||
}
|
||||
|
||||
@@ -43,6 +43,17 @@ static SDLIosMainCallbacksDisplayLink *globalDisplayLink;
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(appIteration:)];
|
||||
// Enable high refresh rates on iOS
|
||||
// To enable this on phones, you should add the following line to Info.plist:
|
||||
// <key>CADisableMinimumFrameDurationOnPhone</key> <true/>
|
||||
// If main callbacks are used then this CADisplayLink will affect framerate, not one in SDL_uikitviewcontroller.
|
||||
if (@available(iOS 15.0, tvOS 15.0, *)) {
|
||||
const SDL_DisplayMode *mode = SDL_GetDesktopDisplayMode(SDL_GetPrimaryDisplay());
|
||||
if (mode && mode->refresh_rate > 60.0f) {
|
||||
int frame_rate = (int)mode->refresh_rate;
|
||||
self.displayLink.preferredFrameRateRange = CAFrameRateRangeMake((frame_rate * 2) / 3, frame_rate, frame_rate);
|
||||
}
|
||||
}
|
||||
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
|
||||
}
|
||||
return self;
|
||||
|
||||
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#if defined(SDL_VIDEO_RENDER_D3D) || \
|
||||
defined(SDL_VIDEO_RENDER_D3D11) || \
|
||||
defined(SDL_VIDEO_RENDER_D3D12) || \
|
||||
defined(SDL_VIDEO_RENDER_VULKAN)
|
||||
|
||||
#include "SDL_d3dmath.h"
|
||||
|
||||
// Direct3D matrix math functions
|
||||
|
||||
Float4X4 MatrixIdentity(void)
|
||||
{
|
||||
Float4X4 m;
|
||||
SDL_zero(m);
|
||||
m.v._11 = 1.0f;
|
||||
m.v._22 = 1.0f;
|
||||
m.v._33 = 1.0f;
|
||||
m.v._44 = 1.0f;
|
||||
return m;
|
||||
}
|
||||
|
||||
Float4X4 MatrixMultiply(Float4X4 M1, Float4X4 M2)
|
||||
{
|
||||
Float4X4 m;
|
||||
m.v._11 = M1.v._11 * M2.v._11 + M1.v._12 * M2.v._21 + M1.v._13 * M2.v._31 + M1.v._14 * M2.v._41;
|
||||
m.v._12 = M1.v._11 * M2.v._12 + M1.v._12 * M2.v._22 + M1.v._13 * M2.v._32 + M1.v._14 * M2.v._42;
|
||||
m.v._13 = M1.v._11 * M2.v._13 + M1.v._12 * M2.v._23 + M1.v._13 * M2.v._33 + M1.v._14 * M2.v._43;
|
||||
m.v._14 = M1.v._11 * M2.v._14 + M1.v._12 * M2.v._24 + M1.v._13 * M2.v._34 + M1.v._14 * M2.v._44;
|
||||
m.v._21 = M1.v._21 * M2.v._11 + M1.v._22 * M2.v._21 + M1.v._23 * M2.v._31 + M1.v._24 * M2.v._41;
|
||||
m.v._22 = M1.v._21 * M2.v._12 + M1.v._22 * M2.v._22 + M1.v._23 * M2.v._32 + M1.v._24 * M2.v._42;
|
||||
m.v._23 = M1.v._21 * M2.v._13 + M1.v._22 * M2.v._23 + M1.v._23 * M2.v._33 + M1.v._24 * M2.v._43;
|
||||
m.v._24 = M1.v._21 * M2.v._14 + M1.v._22 * M2.v._24 + M1.v._23 * M2.v._34 + M1.v._24 * M2.v._44;
|
||||
m.v._31 = M1.v._31 * M2.v._11 + M1.v._32 * M2.v._21 + M1.v._33 * M2.v._31 + M1.v._34 * M2.v._41;
|
||||
m.v._32 = M1.v._31 * M2.v._12 + M1.v._32 * M2.v._22 + M1.v._33 * M2.v._32 + M1.v._34 * M2.v._42;
|
||||
m.v._33 = M1.v._31 * M2.v._13 + M1.v._32 * M2.v._23 + M1.v._33 * M2.v._33 + M1.v._34 * M2.v._43;
|
||||
m.v._34 = M1.v._31 * M2.v._14 + M1.v._32 * M2.v._24 + M1.v._33 * M2.v._34 + M1.v._34 * M2.v._44;
|
||||
m.v._41 = M1.v._41 * M2.v._11 + M1.v._42 * M2.v._21 + M1.v._43 * M2.v._31 + M1.v._44 * M2.v._41;
|
||||
m.v._42 = M1.v._41 * M2.v._12 + M1.v._42 * M2.v._22 + M1.v._43 * M2.v._32 + M1.v._44 * M2.v._42;
|
||||
m.v._43 = M1.v._41 * M2.v._13 + M1.v._42 * M2.v._23 + M1.v._43 * M2.v._33 + M1.v._44 * M2.v._43;
|
||||
m.v._44 = M1.v._41 * M2.v._14 + M1.v._42 * M2.v._24 + M1.v._43 * M2.v._34 + M1.v._44 * M2.v._44;
|
||||
return m;
|
||||
}
|
||||
|
||||
Float4X4 MatrixScaling(float x, float y, float z)
|
||||
{
|
||||
Float4X4 m;
|
||||
SDL_zero(m);
|
||||
m.v._11 = x;
|
||||
m.v._22 = y;
|
||||
m.v._33 = z;
|
||||
m.v._44 = 1.0f;
|
||||
return m;
|
||||
}
|
||||
|
||||
Float4X4 MatrixTranslation(float x, float y, float z)
|
||||
{
|
||||
Float4X4 m;
|
||||
SDL_zero(m);
|
||||
m.v._11 = 1.0f;
|
||||
m.v._22 = 1.0f;
|
||||
m.v._33 = 1.0f;
|
||||
m.v._44 = 1.0f;
|
||||
m.v._41 = x;
|
||||
m.v._42 = y;
|
||||
m.v._43 = z;
|
||||
return m;
|
||||
}
|
||||
|
||||
Float4X4 MatrixRotationX(float r)
|
||||
{
|
||||
float sinR = SDL_sinf(r);
|
||||
float cosR = SDL_cosf(r);
|
||||
Float4X4 m;
|
||||
SDL_zero(m);
|
||||
m.v._11 = 1.0f;
|
||||
m.v._22 = cosR;
|
||||
m.v._23 = sinR;
|
||||
m.v._32 = -sinR;
|
||||
m.v._33 = cosR;
|
||||
m.v._44 = 1.0f;
|
||||
return m;
|
||||
}
|
||||
|
||||
Float4X4 MatrixRotationY(float r)
|
||||
{
|
||||
float sinR = SDL_sinf(r);
|
||||
float cosR = SDL_cosf(r);
|
||||
Float4X4 m;
|
||||
SDL_zero(m);
|
||||
m.v._11 = cosR;
|
||||
m.v._13 = -sinR;
|
||||
m.v._22 = 1.0f;
|
||||
m.v._31 = sinR;
|
||||
m.v._33 = cosR;
|
||||
m.v._44 = 1.0f;
|
||||
return m;
|
||||
}
|
||||
|
||||
Float4X4 MatrixRotationZ(float r)
|
||||
{
|
||||
float sinR = SDL_sinf(r);
|
||||
float cosR = SDL_cosf(r);
|
||||
Float4X4 m;
|
||||
SDL_zero(m);
|
||||
m.v._11 = cosR;
|
||||
m.v._12 = sinR;
|
||||
m.v._21 = -sinR;
|
||||
m.v._22 = cosR;
|
||||
m.v._33 = 1.0f;
|
||||
m.v._44 = 1.0f;
|
||||
return m;
|
||||
}
|
||||
|
||||
#endif // SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11 || SDL_VIDEO_RENDER_D3D12 || SDL_VIDEO_RENDER_VULKAN
|
||||
Loaded 100 of 169 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user