Browse Source

Merge branch 'development' of https://github.com/TorqueGameEngines/Torque3D into alpha41/sfxShanked

# Conflicts:
#	Engine/source/T3D/sfx/sfxEmitter.cpp
AzaezelX 4 months ago
parent
commit
7a97ad6099
100 changed files with 6092 additions and 758 deletions
  1. 90 0
      Engine/lib/sdl/.clang-format
  2. 79 0
      Engine/lib/sdl/.editorconfig
  3. 190 0
      Engine/lib/sdl/.gitignore
  4. 31 0
      Engine/lib/sdl/.wikiheaders-options
  5. 1 0
      Engine/lib/sdl/Android.mk
  6. 258 139
      Engine/lib/sdl/CMakeLists.txt
  7. 1 1
      Engine/lib/sdl/LICENSE.txt
  8. 1 1
      Engine/lib/sdl/Makefile.in
  9. 8 6
      Engine/lib/sdl/Makefile.os2
  10. 9 6
      Engine/lib/sdl/Makefile.w32
  11. 0 119
      Engine/lib/sdl/SDL2.spec
  12. 0 1
      Engine/lib/sdl/VERSION.txt
  13. 7 0
      Engine/lib/sdl/VisualC-GDK/clean.sh
  14. BIN
      Engine/lib/sdl/VisualC-GDK/logos/Logo100x100.png
  15. BIN
      Engine/lib/sdl/VisualC-GDK/logos/Logo150x150.png
  16. BIN
      Engine/lib/sdl/VisualC-GDK/logos/Logo44x44.png
  17. BIN
      Engine/lib/sdl/VisualC-GDK/logos/Logo480x480.png
  18. BIN
      Engine/lib/sdl/VisualC-GDK/logos/SplashScreenImage.png
  19. 19 0
      Engine/lib/sdl/VisualC-GDK/shaders/D3D12_PixelShader_Colors.hlsl
  20. 43 0
      Engine/lib/sdl/VisualC-GDK/shaders/D3D12_PixelShader_NV12_BT601.hlsl
  21. 43 0
      Engine/lib/sdl/VisualC-GDK/shaders/D3D12_PixelShader_NV12_BT709.hlsl
  22. 43 0
      Engine/lib/sdl/VisualC-GDK/shaders/D3D12_PixelShader_NV12_JPEG.hlsl
  23. 43 0
      Engine/lib/sdl/VisualC-GDK/shaders/D3D12_PixelShader_NV21_BT601.hlsl
  24. 43 0
      Engine/lib/sdl/VisualC-GDK/shaders/D3D12_PixelShader_NV21_BT709.hlsl
  25. 43 0
      Engine/lib/sdl/VisualC-GDK/shaders/D3D12_PixelShader_NV21_JPEG.hlsl
  26. 24 0
      Engine/lib/sdl/VisualC-GDK/shaders/D3D12_PixelShader_Textures.hlsl
  27. 46 0
      Engine/lib/sdl/VisualC-GDK/shaders/D3D12_PixelShader_YUV_BT601.hlsl
  28. 46 0
      Engine/lib/sdl/VisualC-GDK/shaders/D3D12_PixelShader_YUV_BT709.hlsl
  29. 46 0
      Engine/lib/sdl/VisualC-GDK/shaders/D3D12_PixelShader_YUV_JPEG.hlsl
  30. 95 0
      Engine/lib/sdl/VisualC-GDK/shaders/D3D12_VertexShader.hlsl
  31. 35 0
      Engine/lib/sdl/VisualC-GDK/shaders/buildshaders.bat
  32. 9 0
      Engine/lib/sdl/VisualC-GDK/tests/testgamecontroller/PackageLayout.xml
  33. 34 0
      Engine/lib/sdl/VisualC-GDK/tests/testgamecontroller/wingdk/MicrosoftGame.config
  34. 29 0
      Engine/lib/sdl/VisualC-GDK/tests/testgamecontroller/xboxone/MicrosoftGame.config
  35. 29 0
      Engine/lib/sdl/VisualC-GDK/tests/testgamecontroller/xboxseries/MicrosoftGame.config
  36. 10 0
      Engine/lib/sdl/VisualC-GDK/tests/testgdk/PackageLayout.xml
  37. 503 0
      Engine/lib/sdl/VisualC-GDK/tests/testgdk/src/testgdk.cpp
  38. 34 0
      Engine/lib/sdl/VisualC-GDK/tests/testgdk/wingdk/MicrosoftGame.config
  39. 29 0
      Engine/lib/sdl/VisualC-GDK/tests/testgdk/xboxone/MicrosoftGame.config
  40. 29 0
      Engine/lib/sdl/VisualC-GDK/tests/testgdk/xboxseries/MicrosoftGame.config
  41. 9 0
      Engine/lib/sdl/VisualC-GDK/tests/testsprite2/PackageLayout.xml
  42. 34 0
      Engine/lib/sdl/VisualC-GDK/tests/testsprite2/wingdk/MicrosoftGame.config
  43. 29 0
      Engine/lib/sdl/VisualC-GDK/tests/testsprite2/xboxone/MicrosoftGame.config
  44. 29 0
      Engine/lib/sdl/VisualC-GDK/tests/testsprite2/xboxseries/MicrosoftGame.config
  45. 5 3
      Engine/lib/sdl/VisualC/pkg-support/cmake/sdl2-config.cmake
  46. 19 0
      Engine/lib/sdl/WhatsNew.txt
  47. 5 5
      Engine/lib/sdl/Xcode-iOS/Demos/src/accelerometer.c
  48. 5 5
      Engine/lib/sdl/Xcode-iOS/Demos/src/fireworks.c
  49. 2 2
      Engine/lib/sdl/Xcode-iOS/Demos/src/happy.c
  50. 3 3
      Engine/lib/sdl/Xcode-iOS/Demos/src/keyboard.c
  51. 2 2
      Engine/lib/sdl/Xcode-iOS/Demos/src/rectangles.c
  52. 2 2
      Engine/lib/sdl/Xcode-iOS/Demos/src/touch.c
  53. 2 2
      Engine/lib/sdl/Xcode/SDL/Info-Framework.plist
  54. 220 68
      Engine/lib/sdl/Xcode/SDL/SDL.xcodeproj/project.pbxproj
  55. 1 1
      Engine/lib/sdl/Xcode/SDL/pkg-support/SDL.info
  56. 12 5
      Engine/lib/sdl/Xcode/SDL/pkg-support/resources/CMake/sdl2-config.cmake
  57. 1 1
      Engine/lib/sdl/Xcode/SDL/pkg-support/resources/License.txt
  58. 685 43
      Engine/lib/sdl/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj
  59. 88 75
      Engine/lib/sdl/acinclude/libtool.m4
  60. 1 1
      Engine/lib/sdl/acinclude/ltoptions.m4
  61. 1 0
      Engine/lib/sdl/android-project-ant/AndroidManifest.xml
  62. 17 0
      Engine/lib/sdl/android-project-ant/ant.properties
  63. 17 0
      Engine/lib/sdl/android-project-ant/build.properties
  64. 93 0
      Engine/lib/sdl/android-project-ant/build.xml
  65. 11 0
      Engine/lib/sdl/android-project-ant/default.properties
  66. 1 0
      Engine/lib/sdl/android-project-ant/jni/Android.mk
  67. 10 0
      Engine/lib/sdl/android-project-ant/jni/Application.mk
  68. 18 0
      Engine/lib/sdl/android-project-ant/jni/src/Android.mk
  69. 12 0
      Engine/lib/sdl/android-project-ant/jni/src/Android_static.mk
  70. 20 0
      Engine/lib/sdl/android-project-ant/proguard-project.txt
  71. 14 0
      Engine/lib/sdl/android-project-ant/project.properties
  72. BIN
      Engine/lib/sdl/android-project-ant/res/drawable-hdpi/ic_launcher.png
  73. BIN
      Engine/lib/sdl/android-project-ant/res/drawable-mdpi/ic_launcher.png
  74. BIN
      Engine/lib/sdl/android-project-ant/res/drawable-xhdpi/ic_launcher.png
  75. BIN
      Engine/lib/sdl/android-project-ant/res/drawable-xxhdpi/ic_launcher.png
  76. 13 0
      Engine/lib/sdl/android-project-ant/res/layout/main.xml
  77. 4 0
      Engine/lib/sdl/android-project-ant/res/values/strings.xml
  78. 1 0
      Engine/lib/sdl/android-project-ant/src
  79. 81 0
      Engine/lib/sdl/android-project/app/proguard-rules.pro
  80. 1 1
      Engine/lib/sdl/android-project/app/src/main/AndroidManifest.xml
  81. 16 1
      Engine/lib/sdl/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java
  82. 9 5
      Engine/lib/sdl/android-project/app/src/main/java/org/libsdl/app/SDL.java
  83. 12 9
      Engine/lib/sdl/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
  84. 9 7
      Engine/lib/sdl/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java
  85. 2 3
      Engine/lib/sdl/android-project/app/src/main/res/values/styles.xml
  86. 2 1
      Engine/lib/sdl/build-scripts/androidbuild.sh
  87. 1470 0
      Engine/lib/sdl/build-scripts/build-release.py
  88. 18 0
      Engine/lib/sdl/build-scripts/cmake-toolchain-mingw64-i686.cmake
  89. 18 0
      Engine/lib/sdl/build-scripts/cmake-toolchain-mingw64-x86_64.cmake
  90. 14 6
      Engine/lib/sdl/build-scripts/config.guess
  91. 563 173
      Engine/lib/sdl/build-scripts/config.sub
  92. 43 0
      Engine/lib/sdl/build-scripts/create-release.py
  93. 2 2
      Engine/lib/sdl/build-scripts/gen_audio_channel_conversion.c
  94. 2 2
      Engine/lib/sdl/build-scripts/gen_audio_resampler_filter.c
  95. 70 52
      Engine/lib/sdl/build-scripts/ltmain.sh
  96. 108 0
      Engine/lib/sdl/build-scripts/release-info.json
  97. 303 0
      Engine/lib/sdl/build-scripts/setup-gdk-desktop.py
  98. 2 2
      Engine/lib/sdl/build-scripts/showrev.sh
  99. 10 2
      Engine/lib/sdl/build-scripts/update-copyright.sh
  100. 1 1
      Engine/lib/sdl/build-scripts/updaterev.sh

+ 90 - 0
Engine/lib/sdl/.clang-format

@@ -0,0 +1,90 @@
+---
+AlignConsecutiveMacros: Consecutive
+AlignConsecutiveAssignments: None
+AlignConsecutiveBitFields: None
+AlignConsecutiveDeclarations: None
+AlignEscapedNewlines: Right
+AlignOperands: Align
+AlignTrailingComments: true
+
+AllowAllArgumentsOnNextLine: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortEnumsOnASingleLine: true
+AllowShortBlocksOnASingleLine: Never
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: Never
+AllowShortLoopsOnASingleLine: false
+
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: MultiLine
+
+# Custom brace breaking
+BreakBeforeBraces: Custom
+BraceWrapping:
+  AfterCaseLabel: true
+  AfterClass: true
+  AfterControlStatement: Never
+  AfterEnum: true
+  AfterFunction: true
+  AfterNamespace: true
+  AfterObjCDeclaration: true
+  AfterStruct: true
+  AfterUnion: true
+  AfterExternBlock: false
+  BeforeElse: false
+  BeforeWhile: false
+  IndentBraces: false
+  SplitEmptyFunction: true
+  SplitEmptyRecord: true
+
+# Make the closing brace of container literals go to a new line
+Cpp11BracedListStyle: false
+
+# Never format includes
+IncludeBlocks: Preserve
+# clang-format version 4.0 through 12.0:
+#SortIncludes: false
+# clang-format version 13.0+:
+#SortIncludes: Never
+
+# No length limit, in case it breaks macros, you can
+# disable it with /* clang-format off/on */ comments
+ColumnLimit: 0
+
+IndentWidth: 4
+ContinuationIndentWidth: 4
+IndentCaseLabels: false
+IndentCaseBlocks: false
+IndentGotoLabels: true
+IndentPPDirectives: None
+IndentExternBlock: NoIndent
+
+PointerAlignment: Right
+SpaceAfterCStyleCast: false
+SpacesInCStyleCastParentheses: false
+SpacesInConditionalStatement: false
+SpacesInContainerLiterals: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCaseColon: false
+SpaceBeforeParens: ControlStatements
+SpaceAroundPointerQualifiers: Default
+SpaceInEmptyBlock: false
+SpaceInEmptyParentheses: false
+
+UseCRLF: false
+UseTab: Never
+
+ForEachMacros:
+  [
+    "spa_list_for_each",
+    "spa_list_for_each_safe",
+    "wl_list_for_each",
+    "wl_array_for_each",
+    "udev_list_entry_foreach",
+  ]
+
+---
+

+ 79 - 0
Engine/lib/sdl/.editorconfig

@@ -0,0 +1,79 @@
+# For format see editorconfig.org
+# Copyright 2022 Collabora Ltd.
+# SPDX-License-Identifier: Zlib
+
+root = true
+
+[*.{c,cg,cpp,gradle,h,java,m,metal,pl,py,S,sh,txt}]
+indent_size = 4
+indent_style = space
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.{html,js,json,m4,yml,yaml,vcxproj,vcxproj.filters}]
+indent_size = 2
+indent_style = space
+
+[*.xml]
+indent_size = 4
+indent_style = space
+
+[{CMakeLists.txt,sdl2-config*.cmake.in,cmake/*.cmake}]
+indent_size = 2
+indent_style = space
+
+[{cmake_uninstall.cmake.in,test/CMakeLists.txt}]
+indent_size = 4
+indent_style = space
+
+[configure.ac]
+# Inconsistently 2-, 4- or occasionally 3-space indented, but mostly 4,
+# so let's use 4 for new code
+indent_size = 4
+indent_style = space
+
+[{Makefile.*,*.mk,*.sln,*.pbxproj,*.plist}]
+indent_size = 8
+indent_style = tab
+tab_width = 8
+
+[Makefile.os2]
+indent_size = 4
+indent_style = space
+
+[test/Makefile.os2]
+indent_size = 2
+indent_style = space
+
+[{src/core/os2/geniconv/makefile,src/core/os2/geniconv/os2cp.c}]
+indent_size = 2
+indent_style = space
+
+[src/joystick/controller_type.*]
+indent_style = tab
+
+[src/joystick/hidapi/steam/*.h]
+indent_style = tab
+
+[src/libm/*.c]
+indent_style = tab
+
+[src/test/SDL_test_{crc32,md5,random}.c]
+indent_size = 2
+indent_style = space
+
+[src/video/yuv2rgb/*.{c,h}]
+indent_style = tab
+
+[wayland-protocols/*.xml]
+indent_size = 2
+indent_style = space
+
+[*.{markdown,md}]
+indent_size = 4
+indent_style = space
+# Markdown syntax treats tabs as 4 spaces
+tab_width = 4
+
+[{*.bat,*.rc}]
+end_of_line = crlf

+ 190 - 0
Engine/lib/sdl/.gitignore

@@ -0,0 +1,190 @@
+aclocal.m4
+autom4te*
+config.cache
+config.log
+config.status
+libtool
+Makefile
+Makefile.rules
+sdl2-config
+sdl2-config.cmake
+sdl2-config-version.cmake
+sdl2.pc
+SDL2.spec
+build
+gen
+Build
+buildbot
+/REVISION.txt
+dist
+
+*.so
+*.so.*
+*.dll
+*.exe
+*.o
+*.obj
+*.res
+*.lib
+*.a
+*.la
+*.dSYM
+*,e1f
+*,ff8
+*.lnk
+*.err
+*.exp
+*.map
+*.orig
+*~
+*.swp
+*.tmp
+*.rej
+
+# for CMake
+CMakeFiles/
+CMakeCache.txt
+cmake_install.cmake
+cmake_uninstall.cmake
+SDL2ConfigVersion.cmake
+.ninja_*
+*.ninja
+
+# for CLion
+.idea
+cmake-build-*
+
+# for Xcode
+*.mode1*
+*.perspective*
+*.pbxuser
+(^|/)build($|/)
+.DS_Store
+xcuserdata
+*.xcworkspace
+
+# for QtCreator
+CMakeLists.txt.user
+build*/
+*.pro.user*
+
+# for Visual C++
+.vs
+Debug
+Release
+*.user
+*.ncb
+*.suo
+*.sdf
+VisualC/tests/controllermap/axis.bmp
+VisualC/tests/controllermap/button.bmp
+VisualC/tests/controllermap/controllermap.bmp
+VisualC/tests/controllermap/controllermap_back.bmp
+VisualC/tests/loopwave/sample.wav
+VisualC/tests/testautomation/CompareSurfaces0001_Reference.bmp
+VisualC/tests/testautomation/CompareSurfaces0001_TestOutput.bmp
+VisualC/tests/testgamecontroller/axis.bmp
+VisualC/tests/testgamecontroller/button.bmp
+VisualC/tests/testgamecontroller/controllermap.bmp
+VisualC/tests/testgamecontroller/controllermap_back.bmp
+VisualC/tests/testoverlay2/moose.dat
+VisualC/tests/testrendertarget/icon.bmp
+VisualC/tests/testrendertarget/sample.bmp
+VisualC/tests/testscale/icon.bmp
+VisualC/tests/testscale/sample.bmp
+VisualC/tests/testsprite2/icon.bmp
+VisualC/tests/testyuv/testyuv.bmp
+VisualC/visualtest/icon.bmp
+VisualC/visualtest/testquit.actions
+VisualC/visualtest/testquit.config
+VisualC/visualtest/testquit.exe
+VisualC/visualtest/testquit.parameters
+VisualC/visualtest/testsprite2.exe
+VisualC/visualtest/testsprite2_sample.actions
+VisualC/visualtest/testsprite2_sample.config
+VisualC/visualtest/testsprite2_sample.parameters
+VisualC-GDK/**/Layout
+VisualC-GDK/shaders/*.h
+
+# for Android
+android-project/local.properties
+android-project/.gradle/
+
+test/checkkeys
+test/checkkeysthreads
+test/controllermap
+test/loopwave
+test/loopwavequeue
+test/testatomic
+test/testaudiocapture
+test/testaudiohotplug
+test/testaudioinfo
+test/testautomation
+test/testbounds
+test/testcustomcursor
+test/testdisplayinfo
+test/testdraw2
+test/testdrawchessboard
+test/testdropfile
+test/testerror
+test/testevdev
+test/testfile
+test/testfilesystem
+test/testgamecontroller
+test/testgeometry
+test/testgesture
+test/testgl2
+test/testgles
+test/testgles2
+test/testhaptic
+test/testhittesting
+test/testhotplug
+test/testiconv
+test/testime
+test/testintersections
+test/testjoystick
+test/testkeys
+test/testloadso
+test/testlocale
+test/testlock
+test/testmessage
+test/testmouse
+test/testmultiaudio
+test/testnative
+test/testoverlay2
+test/testplatform
+test/testpower
+test/testqsort
+test/testrelative
+test/testrendercopyex
+test/testrendertarget
+test/testresample
+test/testrumble
+test/testscale
+test/testsem
+test/testsensor
+test/testshader
+test/testshape
+test/testsprite2
+test/testspriteminimal
+test/teststreaming
+test/testsurround
+test/testthread
+test/testtimer
+test/testurl
+test/testver
+test/testviewport
+test/testvulkan
+test/testwm2
+test/testyuv
+test/torturethread
+
+builddir/
+!build-scripts/
+debian/*.debhelper.log
+debian/*.substvars
+debian/*.tar.gz
+debian/.debhelper/
+debian/files
+debian/libsdl*/
+debian/tmp/

+ 31 - 0
Engine/lib/sdl/.wikiheaders-options

@@ -0,0 +1,31 @@
+projectfullname = Simple Directmedia Layer
+projectshortname = SDL
+incsubdir = include
+wikisubdir = SDL2
+readmesubdir = docs
+apiprefixregex = (SDL_|SDLK_|KMOD_|AUDIO_|[US]int\d+)
+mainincludefname = SDL.h
+versionfname = include/SDL_version.h
+versionmajorregex = \A\#define\s+SDL_MAJOR_VERSION\s+(\d+)\Z
+versionminorregex = \A\#define\s+SDL_MINOR_VERSION\s+(\d+)\Z
+versionpatchregex = \A\#define\s+SDL_PATCHLEVEL\s+(\d+)\Z
+selectheaderregex = \ASDL.*?\.h\Z
+projecturl = https://libsdl.org/
+wikiurl = https://wiki.libsdl.org/SDL2
+bugreporturl = https://github.com/libsdl-org/sdlwiki/issues/new
+warn_about_missing = 0
+#wikipreamble = (This is the legacy documentation for SDL2, the previous stable version; [SDL3](https://wiki.libsdl.org/SDL3/) is the current stable version.)
+wikiheaderfiletext = Defined in [%fname%](https://github.com/libsdl-org/SDL/blob/SDL2/include/%fname%)
+manpageheaderfiletext = Defined in %fname%
+
+# All SDL_config_*.h headers are uncategorized, in case something slips in from them.
+# All SDL_test_* headers become uncategorized, everything else just converts like SDL_audio.h -> Audio
+# A handful of others we fix up in the header itself with /* WIKI CATEGORY: x */ comments.
+headercategoryeval = s/\ASDL_config_.*?\.h\Z//; s/\ASDL_test_.*?\.h\Z//; s/\ASDL_?(.*?)\.h\Z/$1/; ucfirst();
+
+quickrefenabled = 0  # !!! FIXME: maybe later, but there are probably documentation gaps to fix first.
+quickrefcategoryorder = Init,Hints,Error,Version,Properties,Log,Video,Events,Keyboard,Mouse,Touch,Gesture,GameController,Joystick,Haptic,Audio,Timer,Render,LoadSO,Thread,Mutex,Atomic,Filesystem,RWOPS,Pixels,Surface,Blendmode,Rect,Clipboard,Messagebox,Vulkan,Metal,Platform,Power,Sensor,Bits,Endian,Assert,CPUInfo,Locale,System,Misc,GUID,Main,Stdinc
+quickreftitle = SDL2 API Quick Reference
+quickrefurl = https://libsdl.org/
+quickrefdesc = The latest version of this document can be found at https://wiki.libsdl.org/SDL2/QuickReference
+quickrefmacroregex = \A(SDL_Atomic...Ref|SDL_assert.*?|SDL_arraysize|SDL_Swap[BL]E\d\d|SDL_[a-z]+_cast|SDL_Load...)\Z

+ 1 - 0
Engine/lib/sdl/Android.mk

@@ -35,6 +35,7 @@ LOCAL_SRC_FILES := \
 	$(wildcard $(LOCAL_PATH)/src/hidapi/android/*.cpp) \
 	$(wildcard $(LOCAL_PATH)/src/hidapi/android/*.cpp) \
 	$(wildcard $(LOCAL_PATH)/src/joystick/*.c) \
 	$(wildcard $(LOCAL_PATH)/src/joystick/*.c) \
 	$(wildcard $(LOCAL_PATH)/src/joystick/android/*.c) \
 	$(wildcard $(LOCAL_PATH)/src/joystick/android/*.c) \
+	$(wildcard $(LOCAL_PATH)/src/joystick/dummy/*.c) \
 	$(wildcard $(LOCAL_PATH)/src/joystick/hidapi/*.c) \
 	$(wildcard $(LOCAL_PATH)/src/joystick/hidapi/*.c) \
 	$(wildcard $(LOCAL_PATH)/src/joystick/virtual/*.c) \
 	$(wildcard $(LOCAL_PATH)/src/joystick/virtual/*.c) \
 	$(wildcard $(LOCAL_PATH)/src/loadso/dlopen/*.c) \
 	$(wildcard $(LOCAL_PATH)/src/loadso/dlopen/*.c) \

+ 258 - 139
Engine/lib/sdl/CMakeLists.txt

@@ -5,8 +5,8 @@ endif()
 # MSVC runtime library flags are selected by an abstraction.
 # MSVC runtime library flags are selected by an abstraction.
 set(CMAKE_POLICY_DEFAULT_CMP0091 NEW)
 set(CMAKE_POLICY_DEFAULT_CMP0091 NEW)
 
 
-cmake_minimum_required(VERSION 3.0.0...3.5)
-project(SDL2 C CXX)
+cmake_minimum_required(VERSION 3.0.0...3.10)
+project(SDL2 C)
 
 
 if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
 if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
   set(SDL2_SUBPROJECT OFF)
   set(SDL2_SUBPROJECT OFF)
@@ -15,13 +15,15 @@ else()
 endif()
 endif()
 
 
 if (HAIKU)
 if (HAIKU)
+  enable_language(CXX)
   set(LINKER_LANGUAGE CXX)
   set(LINKER_LANGUAGE CXX)
 endif()
 endif()
 
 
 set(EXTRA_LIBS)
 set(EXTRA_LIBS)
 set(EXTRA_LDFLAGS)
 set(EXTRA_LDFLAGS)
 
 
-set(CMAKE_DEPENDS)
+set(CMAKE_LIBS)
+set(PKGCONFIG_LDFLAGS)
 set(PKGCONFIG_DEPENDS)
 set(PKGCONFIG_DEPENDS)
 
 
 # This is a virtual "library" that just exists to collect up compiler and
 # This is a virtual "library" that just exists to collect up compiler and
@@ -33,8 +35,8 @@ set(PKGCONFIG_DEPENDS)
 add_library(sdl-build-options INTERFACE)
 add_library(sdl-build-options INTERFACE)
 
 
 if(WINDOWS_STORE)
 if(WINDOWS_STORE)
-  target_compile_definitions(sdl-build-options INTERFACE "-DSDL_BUILDING_WINRT=1")
-  target_compile_options(sdl-build-options INTERFACE "-ZW")
+  target_compile_definitions(sdl-build-options INTERFACE "-DSDL_BUILDING_WINRT=1" "WINAPI_FAMILY=WINAPI_FAMILY_APP")
+  target_compile_options(sdl-build-options INTERFACE "$<$<COMPILE_LANGUAGE:CXX>:-ZW>" "$<$<COMPILE_LANGUAGE:CXX>:-EHsc>")
 endif()
 endif()
 
 
 # CMake 3.0 expands the "if(${A})" in "set(OFF 1);set(A OFF);if(${A})" to "if(1)"
 # CMake 3.0 expands the "if(${A})" in "set(OFF 1);set(A OFF);if(${A})" to "if(1)"
@@ -86,8 +88,8 @@ endif()
 
 
 # See docs/release_checklist.md
 # See docs/release_checklist.md
 set(SDL_MAJOR_VERSION 2)
 set(SDL_MAJOR_VERSION 2)
-set(SDL_MINOR_VERSION 28)
-set(SDL_MICRO_VERSION 4)
+set(SDL_MINOR_VERSION 32)
+set(SDL_MICRO_VERSION 6)
 set(SDL_VERSION "${SDL_MAJOR_VERSION}.${SDL_MINOR_VERSION}.${SDL_MICRO_VERSION}")
 set(SDL_VERSION "${SDL_MAJOR_VERSION}.${SDL_MINOR_VERSION}.${SDL_MICRO_VERSION}")
 
 
 # Set defaults preventing destination file conflicts
 # Set defaults preventing destination file conflicts
@@ -140,6 +142,7 @@ check_cpu_architecture(x86 SDL_CPU_X86)
 check_cpu_architecture(x64 SDL_CPU_X64)
 check_cpu_architecture(x64 SDL_CPU_X64)
 check_cpu_architecture(arm32 SDL_CPU_ARM32)
 check_cpu_architecture(arm32 SDL_CPU_ARM32)
 check_cpu_architecture(arm64 SDL_CPU_ARM64)
 check_cpu_architecture(arm64 SDL_CPU_ARM64)
+check_cpu_architecture(arm64ec SDL_CPU_ARM64EC)
 check_cpu_architecture(loongarch64 SDL_CPU_LOONGARCH64)
 check_cpu_architecture(loongarch64 SDL_CPU_LOONGARCH64)
 
 
 # Check for 64 or 32 bit
 # Check for 64 or 32 bit
@@ -195,7 +198,7 @@ endif()
 #  so we'll just use libusb when it's available. libusb does not support iOS,
 #  so we'll just use libusb when it's available. libusb does not support iOS,
 #  so we default to yes on iOS.
 #  so we default to yes on iOS.
 #  TODO: Windows can support libusb, the hid.c file just depends on Unix APIs
 #  TODO: Windows can support libusb, the hid.c file just depends on Unix APIs
-if((WINDOWS AND NOT WINDOWS_STORE) OR IOS OR TVOS OR ANDROID)
+if((WINDOWS AND NOT WINDOWS_STORE) OR IOS OR TVOS OR VISIONOS OR WATCHOS OR ANDROID)
   set(HIDAPI_SKIP_LIBUSB TRUE)
   set(HIDAPI_SKIP_LIBUSB TRUE)
 else()
 else()
   set(HIDAPI_SKIP_LIBUSB FALSE)
   set(HIDAPI_SKIP_LIBUSB FALSE)
@@ -238,9 +241,14 @@ if(USE_GCC OR USE_CLANG OR USE_INTELCC OR USE_QCC)
 endif()
 endif()
 
 
 # Default option knobs
 # Default option knobs
-if(UNIX OR MINGW OR MSYS OR (USE_CLANG AND NOT WINDOWS) OR VITA OR PSP OR PS2 OR N3DS)
+if(UNIX OR MINGW OR MSYS OR (USE_CLANG AND NOT WINDOWS) OR VITA OR PSP OR PS2 OR N3DS OR SDL_CPU_ARM64EC)
   set(OPT_DEF_LIBC ON)
   set(OPT_DEF_LIBC ON)
 endif()
 endif()
+if(WINDOWS OR MACOS OR IOS OR TVOS OR VISIONOS OR WATCHOS)
+  set(SDL_SYSTEM_ICONV_DEFAULT OFF)
+else()
+  set(SDL_SYSTEM_ICONV_DEFAULT ON)
+endif()
 
 
 if(NOT ("$ENV{CFLAGS}" STREQUAL ""))
 if(NOT ("$ENV{CFLAGS}" STREQUAL ""))
   if(CMAKE_VERSION VERSION_LESS 3.11.0)
   if(CMAKE_VERSION VERSION_LESS 3.11.0)
@@ -355,6 +363,11 @@ if(VITA OR PSP OR PS2 OR N3DS)
   set(SDL_LOADSO_ENABLED_BY_DEFAULT OFF)
   set(SDL_LOADSO_ENABLED_BY_DEFAULT OFF)
 endif()
 endif()
 
 
+set(SDL_X11_XRANDR_DEFAULT ON)
+if(SOLARIS)
+  set(SDL_X11_XRANDR_DEFAULT OFF)
+endif()
+
 # When defined, respect CMake's BUILD_SHARED_LIBS setting:
 # When defined, respect CMake's BUILD_SHARED_LIBS setting:
 set(SDL_STATIC_ENABLED_BY_DEFAULT ON)
 set(SDL_STATIC_ENABLED_BY_DEFAULT ON)
 if (NOT DEFINED SDL_SHARED_ENABLED_BY_DEFAULT)
 if (NOT DEFINED SDL_SHARED_ENABLED_BY_DEFAULT)
@@ -404,7 +417,7 @@ dep_option(SDL_SSE                 "Use SSE assembly routines" ON "SDL_ASSEMBLY;
 dep_option(SDL_SSE2                "Use SSE2 assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF)
 dep_option(SDL_SSE2                "Use SSE2 assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF)
 dep_option(SDL_SSE3                "Use SSE3 assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF)
 dep_option(SDL_SSE3                "Use SSE3 assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF)
 dep_option(SDL_MMX                 "Use MMX assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF)
 dep_option(SDL_MMX                 "Use MMX assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF)
-dep_option(SDL_3DNOW               "Use 3Dnow! MMX assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF)
+dep_option(SDL_3DNOW               "Use 3Dnow! MMX assembly routines" OFF "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF)
 dep_option(SDL_ALTIVEC             "Use Altivec assembly routines" ON "SDL_ASSEMBLY" OFF)
 dep_option(SDL_ALTIVEC             "Use Altivec assembly routines" ON "SDL_ASSEMBLY" OFF)
 dep_option(SDL_ARMSIMD             "Use SIMD assembly blitters on ARM" OFF "SDL_ASSEMBLY;SDL_CPU_ARM32" OFF)
 dep_option(SDL_ARMSIMD             "Use SIMD assembly blitters on ARM" OFF "SDL_ASSEMBLY;SDL_CPU_ARM32" OFF)
 dep_option(SDL_ARMNEON             "Use NEON assembly blitters on ARM" OFF "SDL_ASSEMBLY;SDL_CPU_ARM32" OFF)
 dep_option(SDL_ARMNEON             "Use NEON assembly blitters on ARM" OFF "SDL_ASSEMBLY;SDL_CPU_ARM32" OFF)
@@ -420,7 +433,8 @@ set_option(SDL_DIRECTFB            "Use DirectFB video driver" OFF)
 dep_option(SDL_DIRECTFB_SHARED     "Dynamically load directfb support" ON "SDL_DIRECTFB" OFF)
 dep_option(SDL_DIRECTFB_SHARED     "Dynamically load directfb support" ON "SDL_DIRECTFB" OFF)
 set_option(SDL_DUMMYVIDEO          "Use dummy video driver" ON)
 set_option(SDL_DUMMYVIDEO          "Use dummy video driver" ON)
 dep_option(SDL_IBUS                "Enable IBus support" ON ${UNIX_SYS} OFF)
 dep_option(SDL_IBUS                "Enable IBus support" ON ${UNIX_SYS} OFF)
-set_option(SDL_SYSTEM_ICONV        "Use iconv() from system-installed libraries" ON)
+set_option(SDL_SYSTEM_ICONV        "Use iconv() from system-installed libraries" ${SDL_SYSTEM_ICONV_DEFAULT})
+set_option(SDL_LIBICONV            "Prefer iconv() from libiconv, if available, over libc version" OFF)
 set_option(SDL_OPENGL              "Include OpenGL support" ON)
 set_option(SDL_OPENGL              "Include OpenGL support" ON)
 set_option(SDL_OPENGLES            "Include OpenGL ES support" ON)
 set_option(SDL_OPENGLES            "Include OpenGL ES support" ON)
 set_option(SDL_PTHREADS            "Use POSIX threads for multi-threading" ${SDL_PTHREADS_ENABLED_BY_DEFAULT})
 set_option(SDL_PTHREADS            "Use POSIX threads for multi-threading" ${SDL_PTHREADS_ENABLED_BY_DEFAULT})
@@ -450,17 +464,19 @@ set_option(SDL_RPATH               "Use an rpath when linking SDL" ${UNIX_SYS})
 set_option(SDL_CLOCK_GETTIME       "Use clock_gettime() instead of gettimeofday()" ${SDL_CLOCK_GETTIME_ENABLED_BY_DEFAULT})
 set_option(SDL_CLOCK_GETTIME       "Use clock_gettime() instead of gettimeofday()" ${SDL_CLOCK_GETTIME_ENABLED_BY_DEFAULT})
 set_option(SDL_X11                 "Use X11 video driver" ${UNIX_SYS})
 set_option(SDL_X11                 "Use X11 video driver" ${UNIX_SYS})
 dep_option(SDL_X11_SHARED          "Dynamically load X11 support" ON "SDL_X11" OFF)
 dep_option(SDL_X11_SHARED          "Dynamically load X11 support" ON "SDL_X11" OFF)
-set(SDL_X11_OPTIONS Xcursor Xdbe XInput Xfixes Xrandr Xscrnsaver XShape)
-foreach(_SUB ${SDL_X11_OPTIONS})
-  string(TOUPPER "SDL_X11_${_SUB}" _OPT)
-  dep_option(${_OPT}               "Enable ${_SUB} support" ON "SDL_X11" OFF)
-endforeach()
+dep_option(SDL_X11_XCURSOR         "Enable Xcursor support" ON SDL_X11 OFF)
+dep_option(SDL_X11_XDBE            "Enable Xdbe support" ON SDL_X11 OFF)
+dep_option(SDL_X11_XINPUT          "Enable XInput support" ON SDL_X11 OFF)
+dep_option(SDL_X11_XFIXES          "Enable Xfixes support" ON SDL_X11 OFF)
+dep_option(SDL_X11_XRANDR          "Enable Xrandr support" "${SDL_X11_XRANDR_DEFAULT}" SDL_X11 OFF)
+dep_option(SDL_X11_XSCRNSAVER      "Enable Xscrnsaver support" ON SDL_X11 OFF)
+dep_option(SDL_X11_XSHAPE          "Enable XShape support" ON SDL_X11 OFF)
 set_option(SDL_WAYLAND             "Use Wayland video driver" ${UNIX_SYS})
 set_option(SDL_WAYLAND             "Use Wayland video driver" ${UNIX_SYS})
 dep_option(SDL_WAYLAND_SHARED      "Dynamically load Wayland support" ON "SDL_WAYLAND" OFF)
 dep_option(SDL_WAYLAND_SHARED      "Dynamically load Wayland support" ON "SDL_WAYLAND" OFF)
 dep_option(SDL_WAYLAND_LIBDECOR    "Use client-side window decorations on Wayland" ON "SDL_WAYLAND" OFF)
 dep_option(SDL_WAYLAND_LIBDECOR    "Use client-side window decorations on Wayland" ON "SDL_WAYLAND" OFF)
 dep_option(SDL_WAYLAND_LIBDECOR_SHARED     "Dynamically load libdecor support" ON "SDL_WAYLAND_LIBDECOR;SDL_WAYLAND_SHARED" OFF)
 dep_option(SDL_WAYLAND_LIBDECOR_SHARED     "Dynamically load libdecor support" ON "SDL_WAYLAND_LIBDECOR;SDL_WAYLAND_SHARED" OFF)
 dep_option(SDL_WAYLAND_QT_TOUCH    "QtWayland server support for Wayland video driver" ON "SDL_WAYLAND" OFF)
 dep_option(SDL_WAYLAND_QT_TOUCH    "QtWayland server support for Wayland video driver" ON "SDL_WAYLAND" OFF)
-set_option(SDL_RPI                 "Use Raspberry Pi video driver" ${UNIX_SYS})
+set_option(SDL_RPI                 "Use Raspberry Pi 0-3 video driver" ${UNIX_SYS})
 set_option(SDL_COCOA               "Use Cocoa video driver" ${APPLE})
 set_option(SDL_COCOA               "Use Cocoa video driver" ${APPLE})
 set_option(SDL_DIRECTX             "Use DirectX for Windows audio/video" ${WINDOWS})
 set_option(SDL_DIRECTX             "Use DirectX for Windows audio/video" ${WINDOWS})
 set_option(SDL_XINPUT              "Use Xinput for Windows" ${WINDOWS})
 set_option(SDL_XINPUT              "Use Xinput for Windows" ${WINDOWS})
@@ -585,11 +601,50 @@ if(USE_GCC OR USE_CLANG OR USE_INTELCC OR USE_QCC)
     endif()
     endif()
   endif()
   endif()
 
 
+  check_c_compiler_flag(-Wundef HAVE_GCC_WUNDEF)
+  if(HAVE_GCC_WUNDEF)
+    list(APPEND EXTRA_CFLAGS "-Wundef")
+  endif()
+
   check_c_compiler_flag(-fno-strict-aliasing HAVE_GCC_NO_STRICT_ALIASING)
   check_c_compiler_flag(-fno-strict-aliasing HAVE_GCC_NO_STRICT_ALIASING)
   if(HAVE_GCC_NO_STRICT_ALIASING)
   if(HAVE_GCC_NO_STRICT_ALIASING)
     list(APPEND EXTRA_CFLAGS "-fno-strict-aliasing")
     list(APPEND EXTRA_CFLAGS "-fno-strict-aliasing")
   endif()
   endif()
 
 
+  check_c_compiler_flag(-Wdocumentation HAVE_GCC_WDOCUMENTATION)
+  if(HAVE_GCC_WDOCUMENTATION)
+    if(SDL_WERROR)
+      check_c_compiler_flag(-Werror=documentation HAVE_GCC_WERROR_DOCUMENTATION)
+      if(HAVE_GCC_WERROR_DOCUMENTATION)
+        list(APPEND EXTRA_CFLAGS "-Werror=documentation")
+      endif()
+    endif()
+     list(APPEND EXTRA_CFLAGS "-Wdocumentation")
+  endif()
+
+  check_c_compiler_flag(-Wdocumentation-unknown-command HAVE_GCC_WDOCUMENTATION_UNKNOWN_COMMAND)
+  if(HAVE_GCC_WDOCUMENTATION_UNKNOWN_COMMAND)
+    if(SDL_WERROR)
+      check_c_compiler_flag(-Werror=documentation-unknown-command HAVE_GCC_WERROR_DOCUMENTATION_UNKNOWN_COMMAND)
+      if(HAVE_GCC_WERROR_DOCUMENTATION_UNKNOWN_COMMAND)
+        list(APPEND EXTRA_CFLAGS "-Werror=documentation-unknown-command")
+      endif()
+    endif()
+    list(APPEND EXTRA_CFLAGS "-Wdocumentation-unknown-command")
+  endif()
+
+  check_c_compiler_flag(-fcomment-block-commands=threadsafety HAVE_GCC_COMMENT_BLOCK_COMMANDS)
+  if(HAVE_GCC_COMMENT_BLOCK_COMMANDS)
+    list(APPEND EXTRA_CFLAGS "-fcomment-block-commands=threadsafety")
+    list(APPEND EXTRA_CFLAGS "-fcomment-block-commands=deprecated")
+  else()
+    check_c_compiler_flag(/clang:-fcomment-block-commands=threadsafety HAVE_CLANG_COMMENT_BLOCK_COMMANDS)
+    if(HAVE_CLANG_COMMENT_BLOCK_COMMANDS)
+      list(APPEND EXTRA_CFLAGS "/clang:-fcomment-block-commands=threadsafety")
+      list(APPEND EXTRA_CFLAGS "/clang:-fcomment-block-commands=deprecated")
+    endif()
+  endif()
+
   check_c_compiler_flag(-Wdeclaration-after-statement HAVE_GCC_WDECLARATION_AFTER_STATEMENT)
   check_c_compiler_flag(-Wdeclaration-after-statement HAVE_GCC_WDECLARATION_AFTER_STATEMENT)
   if(HAVE_GCC_WDECLARATION_AFTER_STATEMENT)
   if(HAVE_GCC_WDECLARATION_AFTER_STATEMENT)
     if(SDL_WERROR)
     if(SDL_WERROR)
@@ -866,7 +921,7 @@ if(SDL_ASSEMBLY)
 
 
     if(SDL_LSX)
     if(SDL_LSX)
       cmake_push_check_state()
       cmake_push_check_state()
-      list(APPEND CMAKE_REQUIRED_FLAGS "-mlsx")
+      set(CMAKE_REQUIRED_FLAGS "-mlsx")
       check_c_source_compiles("
       check_c_source_compiles("
           #ifndef __loongarch_sx
           #ifndef __loongarch_sx
           #error Assembler CPP flag not enabled
           #error Assembler CPP flag not enabled
@@ -881,22 +936,6 @@ if(SDL_ASSEMBLY)
       endif()
       endif()
     endif()
     endif()
 
 
-    if(SDL_LASX)
-      cmake_push_check_state()
-      list(APPEND CMAKE_REQUIRED_FLAGS "-mlasx")
-      check_c_source_compiles("
-          #ifndef __loongarch_asx
-          #error Assembler CPP flag not enabled
-          #endif
-          int main(int argc, char **argv) { return 0; }" CPU_SUPPORTS_LASX)
-      check_include_file("lasxintrin.h" HAVE_LASXINTRIN_H)
-      cmake_pop_check_state()
-      if(CPU_SUPPORTS_LASX AND HAVE_LASXINTRIN_H)
-        list(APPEND EXTRA_CFLAGS "-mlasx")
-        set(HAVE_LASX TRUE)
-      endif()
-    endif()
-
     if(SDL_ARMSIMD)
     if(SDL_ARMSIMD)
       set(ORIG_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
       set(ORIG_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
       set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -x assembler-with-cpp")
       set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -x assembler-with-cpp")
@@ -1026,15 +1065,11 @@ if(SDL_LIBC)
         sys/types.h
         sys/types.h
         wchar.h
         wchar.h
     )
     )
-    if(NOT EMSCRIPTEN)
-      list(APPEND headers_to_check libunwind.h)
-    endif()
     foreach(_HEADER ${headers_to_check})
     foreach(_HEADER ${headers_to_check})
       string(TOUPPER "HAVE_${_HEADER}" _UPPER)
       string(TOUPPER "HAVE_${_HEADER}" _UPPER)
       string(REGEX REPLACE "[./]" "_" _HAVE_H ${_UPPER})
       string(REGEX REPLACE "[./]" "_" _HAVE_H ${_UPPER})
       check_include_file("${_HEADER}" ${_HAVE_H})
       check_include_file("${_HEADER}" ${_HAVE_H})
     endforeach()
     endforeach()
-    check_include_file(linux/input.h HAVE_LINUX_INPUT_H)
 
 
     set(STDC_HEADER_NAMES "stddef.h;stdarg.h;stdlib.h;string.h;stdio.h;wchar.h;float.h")
     set(STDC_HEADER_NAMES "stddef.h;stdarg.h;stdlib.h;string.h;stdio.h;wchar.h;float.h")
     check_include_files("${STDC_HEADER_NAMES}" STDC_HEADERS)
     check_include_files("${STDC_HEADER_NAMES}" STDC_HEADERS)
@@ -1066,6 +1101,8 @@ if(SDL_LIBC)
     check_symbol_exists(getauxval "sys/auxv.h" HAVE_GETAUXVAL)
     check_symbol_exists(getauxval "sys/auxv.h" HAVE_GETAUXVAL)
     check_symbol_exists(elf_aux_info "sys/auxv.h" HAVE_ELF_AUX_INFO)
     check_symbol_exists(elf_aux_info "sys/auxv.h" HAVE_ELF_AUX_INFO)
     check_symbol_exists(poll "poll.h" HAVE_POLL)
     check_symbol_exists(poll "poll.h" HAVE_POLL)
+    check_symbol_exists(memfd_create "sys/mman.h" HAVE_MEMFD_CREATE)
+    check_symbol_exists(posix_fallocate "fcntl.h" HAVE_POSIX_FALLOCATE)
 
 
     check_library_exists(m pow "" HAVE_LIBM)
     check_library_exists(m pow "" HAVE_LIBM)
     if(HAVE_LIBM)
     if(HAVE_LIBM)
@@ -1088,16 +1125,31 @@ if(SDL_LIBC)
     endif()
     endif()
 
 
     if(SDL_SYSTEM_ICONV)
     if(SDL_SYSTEM_ICONV)
-      check_library_exists(iconv iconv_open "" HAVE_LIBICONV)
-      if(HAVE_LIBICONV)
-        list(APPEND EXTRA_LIBS iconv)
+      check_c_source_compiles("
+        #define LIBICONV_PLUG 1 /* in case libiconv header is in include path */
+        #include <stddef.h>
+        #include <iconv.h>
+        int main(int argc, char **argv) {
+            return !iconv_open(NULL,NULL);
+        }" ICONV_IN_LIBC)
+
+      cmake_push_check_state()
+      list(APPEND CMAKE_REQUIRED_LIBRARIES iconv)
+      check_c_source_compiles("
+        #include <stddef.h>
+        #include <iconv.h>
+        int main(int argc, char **argv) {
+            return !iconv_open(NULL,NULL);
+        }" ICONV_IN_LIBICONV)
+      cmake_pop_check_state()
+
+      if(ICONV_IN_LIBC OR ICONV_IN_LIBICONV)
         set(HAVE_ICONV 1)
         set(HAVE_ICONV 1)
         set(HAVE_SYSTEM_ICONV TRUE)
         set(HAVE_SYSTEM_ICONV TRUE)
-      else()
-        check_library_exists(c iconv_open "" HAVE_BUILTIN_ICONV)
-        if(HAVE_BUILTIN_ICONV)
-          set(HAVE_ICONV 1)
-          set(HAVE_SYSTEM_ICONV TRUE)
+        if(ICONV_IN_LIBICONV AND (SDL_LIBICONV OR (NOT ICONV_IN_LIBC)))
+          set(SDL_USE_LIBICONV 1)
+          set(HAVE_LIBICONV TRUE)
+          list(APPEND EXTRA_LIBS iconv)
         endif()
         endif()
       endif()
       endif()
     endif()
     endif()
@@ -1408,10 +1460,7 @@ elseif(EMSCRIPTEN)
   endif()
   endif()
 
 
   CheckPTHREAD()
   CheckPTHREAD()
-
-  if(HAVE_LIBUNWIND_H)
-    list(APPEND EXTRA_TEST_LIBS unwind)
-  endif()
+  CheckLibUnwind()
 
 
 elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
 elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
   if(SDL_AUDIO)
   if(SDL_AUDIO)
@@ -1479,7 +1528,7 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
         #ifndef EVIOCGNAME
         #ifndef EVIOCGNAME
         #error EVIOCGNAME() ioctl not available
         #error EVIOCGNAME() ioctl not available
         #endif
         #endif
-        int main(int argc, char** argv) { return 0; }" HAVE_INPUT_EVENTS)
+        int main(int argc, char** argv) { return 0; }" HAVE_LINUX_INPUT_H)
 
 
     if(LINUX)
     if(LINUX)
       check_c_source_compiles("
       check_c_source_compiles("
@@ -1515,11 +1564,11 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
           }" HAVE_INPUT_WSCONS)
           }" HAVE_INPUT_WSCONS)
     endif()
     endif()
 
 
-    if(HAVE_INPUT_EVENTS)
+    if(HAVE_LINUX_INPUT_H)
       set(SDL_INPUT_LINUXEV 1)
       set(SDL_INPUT_LINUXEV 1)
     endif()
     endif()
 
 
-    if(SDL_HAPTIC AND HAVE_INPUT_EVENTS)
+    if(SDL_HAPTIC AND HAVE_LINUX_INPUT_H)
       set(SDL_HAPTIC_LINUX 1)
       set(SDL_HAPTIC_LINUX 1)
       file(GLOB HAPTIC_SOURCES ${SDL2_SOURCE_DIR}/src/haptic/linux/*.c)
       file(GLOB HAPTIC_SOURCES ${SDL2_SOURCE_DIR}/src/haptic/linux/*.c)
       list(APPEND SOURCE_FILES ${HAPTIC_SOURCES})
       list(APPEND SOURCE_FILES ${HAPTIC_SOURCES})
@@ -1582,15 +1631,8 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
         endif()
         endif()
       endif()
       endif()
 
 
-      if(HAVE_LIBUNWIND_H)
-        # We've already found the header, so link the lib if present.
-        # NB: This .pc file is not present on FreeBSD where the implicitly
-        # linked base system libgcc_s includes all libunwind ABI.
-        pkg_search_module(UNWIND libunwind)
-        pkg_search_module(UNWIND_GENERIC libunwind-generic)
-        list(APPEND EXTRA_TEST_LIBS ${UNWIND_LIBRARIES} ${UNWIND_GENERIC_LIBRARIES})
-      endif()
     endif()
     endif()
+    CheckLibUnwind()
 
 
     if(HAVE_DBUS_DBUS_H)
     if(HAVE_DBUS_DBUS_H)
       list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_dbus.c")
       list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_dbus.c")
@@ -1612,7 +1654,7 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
       list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_udev.c")
       list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_udev.c")
     endif()
     endif()
 
 
-    if(HAVE_INPUT_EVENTS)
+    if(HAVE_LINUX_INPUT_H)
       list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_evdev.c")
       list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_evdev.c")
       list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_evdev_kbd.c")
       list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_evdev_kbd.c")
     endif()
     endif()
@@ -1621,6 +1663,11 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
       list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/freebsd/SDL_evdev_kbd_freebsd.c")
       list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/freebsd/SDL_evdev_kbd_freebsd.c")
     endif()
     endif()
 
 
+    if(HAVE_INPUT_WSCONS)
+      list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/openbsd/SDL_wscons_kbd.c")
+      list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/openbsd/SDL_wscons_mouse.c")
+    endif()
+
     # Always compiled for Linux, unconditionally:
     # Always compiled for Linux, unconditionally:
     list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_evdev_capabilities.c")
     list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_evdev_capabilities.c")
     list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_threadprio.c")
     list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_threadprio.c")
@@ -1637,7 +1684,7 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
     if(FREEBSD OR NETBSD OR OPENBSD OR BSDI)
     if(FREEBSD OR NETBSD OR OPENBSD OR BSDI)
       CheckUSBHID()
       CheckUSBHID()
     endif()
     endif()
-    if(LINUX AND HAVE_LINUX_INPUT_H AND NOT ANDROID)
+    if((LINUX OR FREEBSD) AND HAVE_LINUX_INPUT_H AND NOT ANDROID)
       set(SDL_JOYSTICK_LINUX 1)
       set(SDL_JOYSTICK_LINUX 1)
       file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/linux/*.c ${SDL2_SOURCE_DIR}/src/joystick/steam/*.c)
       file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/linux/*.c ${SDL2_SOURCE_DIR}/src/joystick/steam/*.c)
       list(APPEND SOURCE_FILES ${JOYSTICK_SOURCES})
       list(APPEND SOURCE_FILES ${JOYSTICK_SOURCES})
@@ -1736,18 +1783,11 @@ elseif(WINDOWS)
   list(APPEND SOURCE_FILES ${CORE_SOURCES})
   list(APPEND SOURCE_FILES ${CORE_SOURCES})
 
 
   if(WINDOWS_STORE)
   if(WINDOWS_STORE)
+    enable_language(CXX)
     file(GLOB WINRT_SOURCE_FILES ${SDL2_SOURCE_DIR}/src/core/winrt/*.c ${SDL2_SOURCE_DIR}/src/core/winrt/*.cpp)
     file(GLOB WINRT_SOURCE_FILES ${SDL2_SOURCE_DIR}/src/core/winrt/*.c ${SDL2_SOURCE_DIR}/src/core/winrt/*.cpp)
     list(APPEND SOURCE_FILES ${WINRT_SOURCE_FILES})
     list(APPEND SOURCE_FILES ${WINRT_SOURCE_FILES})
   endif()
   endif()
 
 
-  if(MSVC AND NOT SDL_LIBC)
-    # Prevent codegen that would use the VC runtime libraries.
-    set_property(DIRECTORY . APPEND PROPERTY COMPILE_OPTIONS "/GS-;/Gs1048576")
-    if(NOT ARCH_64 AND NOT CMAKE_GENERATOR_PLATFORM STREQUAL "ARM")
-      set_property(DIRECTORY . APPEND PROPERTY COMPILE_OPTIONS "/arch:SSE")
-    endif()
-  endif()
-
   if(SDL_MISC)
   if(SDL_MISC)
     if(WINDOWS_STORE)
     if(WINDOWS_STORE)
       file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/winrt/*.cpp)
       file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/winrt/*.cpp)
@@ -1773,13 +1813,11 @@ elseif(WINDOWS)
     check_include_file(d3d9.h HAVE_D3D_H)
     check_include_file(d3d9.h HAVE_D3D_H)
     check_include_file(d3d11_1.h HAVE_D3D11_H)
     check_include_file(d3d11_1.h HAVE_D3D11_H)
     check_c_source_compiles("
     check_c_source_compiles("
-      #include <winsdkver.h>
-      #include <sdkddkver.h>
       #include <d3d12.h>
       #include <d3d12.h>
+      #include <d3d12sdklayers.h>
       ID3D12Device1 *device;
       ID3D12Device1 *device;
-      #if WDK_NTDDI_VERSION > 0x0A000008
-      int main(int argc, char **argv) { return 0; }
-      #endif" HAVE_D3D12_H)
+      int main(int argc, char **argv) {return 0; }
+      " HAVE_D3D12_H)
     check_include_file(ddraw.h HAVE_DDRAW_H)
     check_include_file(ddraw.h HAVE_DDRAW_H)
     check_include_file(dsound.h HAVE_DSOUND_H)
     check_include_file(dsound.h HAVE_DSOUND_H)
     check_include_file(dinput.h HAVE_DINPUT_H)
     check_include_file(dinput.h HAVE_DINPUT_H)
@@ -1791,8 +1829,10 @@ elseif(WINDOWS)
       set(HAVE_DIRECTX TRUE)
       set(HAVE_DIRECTX TRUE)
       if(NOT MINGW AND NOT USE_WINSDK_DIRECTX)
       if(NOT MINGW AND NOT USE_WINSDK_DIRECTX)
       # TODO: change $ENV{DXSDL_DIR} to get the path from the include checks
       # TODO: change $ENV{DXSDL_DIR} to get the path from the include checks
-        target_link_directories(sdl-build-options INTERFACE "$$ENV{DXSDK_DIR}\\lib\\${PROCESSOR_ARCH}")
-        target_include_directories(sdl-build-options INTERFACE "$ENV{DXSDK_DIR}\\Include")
+        file(TO_CMAKE_PATH "$ENV{DXSDK_DIR}\\lib\\${PROCESSOR_ARCH}" SDL2_TMP_DXSDK_LIB_DIR)
+        target_link_directories(sdl-build-options INTERFACE "${SDL2_TMP_DXSDK_LIB_DIR}")
+        file(TO_CMAKE_PATH "$ENV{DXSDK_DIR}\\Include" SDL2_TMP_DXSDK_INCLUDE_DIR)
+        target_include_directories(sdl-build-options INTERFACE "${SDL2_TMP_DXSDK_INCLUDE_DIR}")
       endif()
       endif()
     endif()
     endif()
     set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
     set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
@@ -1804,16 +1844,6 @@ elseif(WINDOWS)
       #include <windows.h>
       #include <windows.h>
       #include <xinput.h>
       #include <xinput.h>
       int main(int argc, char **argv) { return 0; }" HAVE_XINPUT_H)
       int main(int argc, char **argv) { return 0; }" HAVE_XINPUT_H)
-    check_c_source_compiles("
-      #include <windows.h>
-      #include <xinput.h>
-      XINPUT_GAMEPAD_EX x1;
-      int main(int argc, char **argv) { return 0; }" HAVE_XINPUT_GAMEPAD_EX)
-    check_c_source_compiles("
-      #include <windows.h>
-      #include <xinput.h>
-      XINPUT_STATE_EX s1;
-      int main(int argc, char **argv) { return 0; }" HAVE_XINPUT_STATE_EX)
     check_c_source_compiles("
     check_c_source_compiles("
       #define COBJMACROS
       #define COBJMACROS
       #include <windows.gaming.input.h>
       #include <windows.gaming.input.h>
@@ -2037,6 +2067,7 @@ elseif(WINDOWS)
     endif()
     endif()
   endif()
   endif()
 
 
+  enable_language(RC)
   file(GLOB VERSION_SOURCES ${SDL2_SOURCE_DIR}/src/main/windows/*.rc)
   file(GLOB VERSION_SOURCES ${SDL2_SOURCE_DIR}/src/main/windows/*.rc)
   file(GLOB SDLMAIN_SOURCES ${SDL2_SOURCE_DIR}/src/main/windows/*.c)
   file(GLOB SDLMAIN_SOURCES ${SDL2_SOURCE_DIR}/src/main/windows/*.c)
   if(MINGW OR CYGWIN)
   if(MINGW OR CYGWIN)
@@ -2054,7 +2085,7 @@ elseif(APPLE)
   # !!! FIXME: we need Carbon for some very old API calls in
   # !!! FIXME: we need Carbon for some very old API calls in
   # !!! FIXME:  src/video/cocoa/SDL_cocoakeyboard.c, but we should figure out
   # !!! FIXME:  src/video/cocoa/SDL_cocoakeyboard.c, but we should figure out
   # !!! FIXME:  how to dump those.
   # !!! FIXME:  how to dump those.
-  if(DARWIN OR MACOSX)
+  if(MACOS)
     set(SDL_FRAMEWORK_COCOA 1)
     set(SDL_FRAMEWORK_COCOA 1)
     set(SDL_FRAMEWORK_CARBON 1)
     set(SDL_FRAMEWORK_CARBON 1)
   endif()
   endif()
@@ -2068,12 +2099,12 @@ elseif(APPLE)
     set(HAVE_SDL_FILE TRUE)
     set(HAVE_SDL_FILE TRUE)
   endif()
   endif()
 
 
-  if(IOS OR TVOS)
+  if(IOS OR TVOS OR VISIONOS OR WATCHOS)
     file(GLOB SDLMAIN_SOURCES ${SDL2_SOURCE_DIR}/src/main/uikit/*.c)
     file(GLOB SDLMAIN_SOURCES ${SDL2_SOURCE_DIR}/src/main/uikit/*.c)
   endif()
   endif()
 
 
   if(SDL_MISC)
   if(SDL_MISC)
-    if(IOS OR TVOS)
+    if(IOS OR TVOS OR VISIONOS OR WATCHOS)
       file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/ios/*.m)
       file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/ios/*.m)
     else()
     else()
       file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/macosx/*.m)
       file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/macosx/*.m)
@@ -2098,10 +2129,10 @@ elseif(APPLE)
 
 
   if(SDL_JOYSTICK)
   if(SDL_JOYSTICK)
     file(GLOB MFI_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/iphoneos/*.m)
     file(GLOB MFI_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/iphoneos/*.m)
-    if(IOS OR TVOS)
+    if(IOS OR TVOS OR VISIONOS OR WATCHOS)
       file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/steam/*.c)
       file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/steam/*.c)
       set(SDL_JOYSTICK_MFI 1)
       set(SDL_JOYSTICK_MFI 1)
-      if(IOS)
+      if(IOS OR VISIONOS OR WATCHOS)
         set(SDL_FRAMEWORK_COREMOTION 1)
         set(SDL_FRAMEWORK_COREMOTION 1)
       endif()
       endif()
       set(SDL_FRAMEWORK_GAMECONTROLLER 1)
       set(SDL_FRAMEWORK_GAMECONTROLLER 1)
@@ -2142,7 +2173,7 @@ elseif(APPLE)
   endif()
   endif()
 
 
   if(SDL_HAPTIC)
   if(SDL_HAPTIC)
-    if (IOS OR TVOS)
+    if(IOS OR TVOS OR VISIONOS OR WATCHOS)
       file(GLOB HAPTIC_SOURCES ${SDL2_SOURCE_DIR}/src/haptic/dummy/*.c)
       file(GLOB HAPTIC_SOURCES ${SDL2_SOURCE_DIR}/src/haptic/dummy/*.c)
       set(SDL_HAPTIC_DUMMY 1)
       set(SDL_HAPTIC_DUMMY 1)
     else()
     else()
@@ -2156,7 +2187,7 @@ elseif(APPLE)
   endif()
   endif()
 
 
   if(SDL_POWER)
   if(SDL_POWER)
-    if (IOS OR TVOS)
+    if(IOS OR TVOS OR VISIONOS OR WATCHOS)
       file(GLOB POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/uikit/*.m)
       file(GLOB POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/uikit/*.m)
       set(SDL_POWER_UIKIT 1)
       set(SDL_POWER_UIKIT 1)
     else()
     else()
@@ -2189,7 +2220,7 @@ elseif(APPLE)
   endif()
   endif()
 
 
   if(SDL_SENSOR)
   if(SDL_SENSOR)
-    if(IOS)
+    if(IOS OR VISIONOS OR WATCHOS)
       set(SDL_SENSOR_COREMOTION 1)
       set(SDL_SENSOR_COREMOTION 1)
       set(HAVE_SDL_SENSORS TRUE)
       set(HAVE_SDL_SENSORS TRUE)
       file(GLOB SENSOR_SOURCES ${SDL2_SOURCE_DIR}/src/sensor/coremotion/*.m)
       file(GLOB SENSOR_SOURCES ${SDL2_SOURCE_DIR}/src/sensor/coremotion/*.m)
@@ -2199,7 +2230,7 @@ elseif(APPLE)
 
 
   # iOS hack needed - http://code.google.com/p/ios-cmake/ ?
   # iOS hack needed - http://code.google.com/p/ios-cmake/ ?
   if(SDL_VIDEO)
   if(SDL_VIDEO)
-    if (IOS OR TVOS)
+    if(IOS OR TVOS OR VISIONOS OR WATCHOS)
       set(SDL_VIDEO_DRIVER_UIKIT 1)
       set(SDL_VIDEO_DRIVER_UIKIT 1)
       set(SDL_FRAMEWORK_COREGRAPHICS 1)
       set(SDL_FRAMEWORK_COREGRAPHICS 1)
       set(SDL_FRAMEWORK_QUARTZCORE 1)
       set(SDL_FRAMEWORK_QUARTZCORE 1)
@@ -2220,7 +2251,7 @@ elseif(APPLE)
     endif()
     endif()
 
 
     if(SDL_OPENGLES)
     if(SDL_OPENGLES)
-      if(IOS OR TVOS)
+      if(IOS OR TVOS OR VISIONOS OR WATCHOS)
         set(SDL_FRAMEWORK_OPENGLES 1)
         set(SDL_FRAMEWORK_OPENGLES 1)
         set(SDL_VIDEO_OPENGL_ES 1)
         set(SDL_VIDEO_OPENGL_ES 1)
         set(SDL_VIDEO_RENDER_OGL_ES 1)
         set(SDL_VIDEO_RENDER_OGL_ES 1)
@@ -2263,73 +2294,96 @@ elseif(APPLE)
     endif()
     endif()
   endif()
   endif()
 
 
+  # Minimum version for $<LINK_LIBRARY:feature,library-list>
+  cmake_minimum_required(VERSION 3.24)
+
   # Actually load the frameworks at the end so we don't duplicate include.
   # Actually load the frameworks at the end so we don't duplicate include.
   if(SDL_FRAMEWORK_COREVIDEO)
   if(SDL_FRAMEWORK_COREVIDEO)
-    list(APPEND EXTRA_LDFLAGS "-Wl,-framework,CoreVideo")
+    list(APPEND PKGCONFIG_LDFLAGS "-Wl,-framework,CoreVideo")
+    list(APPEND CMAKE_LIBS "$<LINK_LIBRARY:FRAMEWORK,CoreVideo>")
   endif()
   endif()
   if(SDL_FRAMEWORK_COCOA)
   if(SDL_FRAMEWORK_COCOA)
-    list(APPEND EXTRA_LDFLAGS "-Wl,-framework,Cocoa")
+    list(APPEND PKGCONFIG_LDFLAGS "-Wl,-framework,Cocoa")
+    list(APPEND CMAKE_LIBS "$<LINK_LIBRARY:FRAMEWORK,Cocoa>")
   endif()
   endif()
   if(SDL_FRAMEWORK_IOKIT)
   if(SDL_FRAMEWORK_IOKIT)
-    list(APPEND EXTRA_LDFLAGS "-Wl,-framework,IOKit")
+    list(APPEND PKGCONFIG_LDFLAGS "-Wl,-framework,IOKit")
+    list(APPEND CMAKE_LIBS "$<LINK_LIBRARY:FRAMEWORK,IOKit>")
   endif()
   endif()
   if(SDL_FRAMEWORK_FF)
   if(SDL_FRAMEWORK_FF)
-    list(APPEND EXTRA_LDFLAGS "-Wl,-framework,ForceFeedback")
+    list(APPEND PKGCONFIG_LDFLAGS "-Wl,-framework,ForceFeedback")
+    list(APPEND CMAKE_LIBS "$<LINK_LIBRARY:FRAMEWORK,ForceFeedback>")
   endif()
   endif()
   if(SDL_FRAMEWORK_CARBON)
   if(SDL_FRAMEWORK_CARBON)
-    list(APPEND EXTRA_LDFLAGS "-Wl,-framework,Carbon")
+    list(APPEND PKGCONFIG_LDFLAGS "-Wl,-framework,Carbon")
+    list(APPEND CMAKE_LIBS "$<LINK_LIBRARY:FRAMEWORK,Carbon>")
   endif()
   endif()
   if(SDL_FRAMEWORK_COREAUDIO)
   if(SDL_FRAMEWORK_COREAUDIO)
-    list(APPEND EXTRA_LDFLAGS "-Wl,-framework,CoreAudio")
+    list(APPEND PKGCONFIG_LDFLAGS "-Wl,-framework,CoreAudio")
+    list(APPEND CMAKE_LIBS "$<LINK_LIBRARY:FRAMEWORK,CoreAudio>")
   endif()
   endif()
   if(SDL_FRAMEWORK_AUDIOTOOLBOX)
   if(SDL_FRAMEWORK_AUDIOTOOLBOX)
-    list(APPEND EXTRA_LDFLAGS "-Wl,-framework,AudioToolbox")
+    list(APPEND PKGCONFIG_LDFLAGS "-Wl,-framework,AudioToolbox")
+    list(APPEND CMAKE_LIBS "$<LINK_LIBRARY:FRAMEWORK,AudioToolbox>")
   endif()
   endif()
   if(SDL_FRAMEWORK_AVFOUNDATION)
   if(SDL_FRAMEWORK_AVFOUNDATION)
-    list(APPEND EXTRA_LDFLAGS "-Wl,-framework,AVFoundation")
+    list(APPEND PKGCONFIG_LDFLAGS "-Wl,-framework,AVFoundation")
+    list(APPEND CMAKE_LIBS "$<LINK_LIBRARY:FRAMEWORK,AVFoundation>")
   endif()
   endif()
   if(SDL_FRAMEWORK_COREBLUETOOTH)
   if(SDL_FRAMEWORK_COREBLUETOOTH)
-    list(APPEND EXTRA_LDFLAGS "-Wl,-framework,CoreBluetooth")
+    list(APPEND PKGCONFIG_LDFLAGS "-Wl,-framework,CoreBluetooth")
+    list(APPEND CMAKE_LIBS "$<LINK_LIBRARY:FRAMEWORK,CoreBluetooth>")
   endif()
   endif()
   if(SDL_FRAMEWORK_COREGRAPHICS)
   if(SDL_FRAMEWORK_COREGRAPHICS)
-    list(APPEND EXTRA_LDFLAGS "-Wl,-framework,CoreGraphics")
+    list(APPEND PKGCONFIG_LDFLAGS "-Wl,-framework,CoreGraphics")
+    list(APPEND CMAKE_LIBS "$<LINK_LIBRARY:FRAMEWORK,CoreGraphics>")
   endif()
   endif()
   if(SDL_FRAMEWORK_COREMOTION)
   if(SDL_FRAMEWORK_COREMOTION)
-    list(APPEND EXTRA_LDFLAGS "-Wl,-framework,CoreMotion")
+    list(APPEND PKGCONFIG_LDFLAGS "-Wl,-framework,CoreMotion")
+    list(APPEND CMAKE_LIBS "$<LINK_LIBRARY:FRAMEWORK,Coremotion>")
   endif()
   endif()
   if(SDL_FRAMEWORK_FOUNDATION)
   if(SDL_FRAMEWORK_FOUNDATION)
-    list(APPEND EXTRA_LDFLAGS "-Wl,-framework,Foundation")
+    list(APPEND PKGCONFIG_LDFLAGS "-Wl,-framework,Foundation")
+    list(APPEND CMAKE_LIBS "$<LINK_LIBRARY:FRAMEWORK,Foundation>")
   endif()
   endif()
   if(SDL_FRAMEWORK_GAMECONTROLLER)
   if(SDL_FRAMEWORK_GAMECONTROLLER)
     find_library(GAMECONTROLLER GameController)
     find_library(GAMECONTROLLER GameController)
     if(GAMECONTROLLER)
     if(GAMECONTROLLER)
-      list(APPEND EXTRA_LDFLAGS "-Wl,-weak_framework,GameController")
+      list(APPEND PKGCONFIG_LDFLAGS "-Wl,-weak_framework,GameController")
+      list(APPEND CMAKE_LIBS "$<LINK_LIBRARY:WEAK_FRAMEWORK,GameController>")
     endif()
     endif()
   endif()
   endif()
   if(SDL_FRAMEWORK_METAL)
   if(SDL_FRAMEWORK_METAL)
-    if(IOS OR TVOS)
-      list(APPEND EXTRA_LDFLAGS "-Wl,-framework,Metal")
+    if(IOS OR TVOS OR VISIONOS OR WATCHOS)
+      list(APPEND PKGCONFIG_LDFLAGS "-Wl,-framework,Metal")
+      list(APPEND CMAKE_LIBS "$<LINK_LIBRARY:FRAMEWORK,Metal>")
     else()
     else()
-      list(APPEND EXTRA_LDFLAGS "-Wl,-weak_framework,Metal")
+      list(APPEND PKGCONFIG_LDFLAGS "-Wl,-weak_framework,Metal")
+      list(APPEND CMAKE_LIBS "$<LINK_LIBRARY:WEAK_FRAMEWORK,Metal>")
     endif()
     endif()
   endif()
   endif()
   if(SDL_FRAMEWORK_OPENGLES)
   if(SDL_FRAMEWORK_OPENGLES)
-    list(APPEND EXTRA_LDFLAGS "-Wl,-framework,OpenGLES")
+    list(APPEND PKGCONFIG_LDFLAGS "-Wl,-framework,OpenGLES")
+    list(APPEND CMAKE_LIBS "$<LINK_LIBRARY:FRAMEWORK,OpenGLES>")
   endif()
   endif()
   if(SDL_FRAMEWORK_QUARTZCORE)
   if(SDL_FRAMEWORK_QUARTZCORE)
-    if(IOS OR TVOS)
-      list(APPEND EXTRA_LDFLAGS "-Wl,-framework,QuartzCore")
+    if(IOS OR TVOS OR VISIONOS OR WATCHOS)
+      list(APPEND PKGCONFIG_LDFLAGS "-Wl,-framework,QuartzCore")
+      list(APPEND CMAKE_LIBS "$<LINK_LIBRARY:FRAMEWORK,QuartzCore>")
     else()
     else()
-      list(APPEND EXTRA_LDFLAGS "-Wl,-weak_framework,QuartzCore")
+      list(APPEND PKGCONFIG_LDFLAGS "-Wl,-weak_framework,QuartzCore")
+      list(APPEND CMAKE_LIBS "$<LINK_LIBRARY:WEAK_FRAMEWORK,QuartzCore>")
     endif()
     endif()
   endif()
   endif()
   if(SDL_FRAMEWORK_UIKIT)
   if(SDL_FRAMEWORK_UIKIT)
-    list(APPEND EXTRA_LDFLAGS "-Wl,-framework,UIKit")
+    list(APPEND PKGCONFIG_LDFLAGS "-Wl,-framework,UIKit")
+    list(APPEND CMAKE_LIBS "$<LINK_LIBRARY:FRAMEWORK,UIKit>")
   endif()
   endif()
   if(SDL_FRAMEWORK_COREHAPTICS)
   if(SDL_FRAMEWORK_COREHAPTICS)
     find_library(COREHAPTICS CoreHaptics)
     find_library(COREHAPTICS CoreHaptics)
     if(COREHAPTICS)
     if(COREHAPTICS)
-      list(APPEND EXTRA_LDFLAGS "-Wl,-weak_framework,CoreHaptics")
+      list(APPEND PKGCONFIG_LDFLAGS "-Wl,-weak_framework,CoreHaptics")
+      list(APPEND CMAKE_LIBS "$<LINK_LIBRARY:WEAK_FRAMEWORK,CoreHaptics>")
     endif()
     endif()
   endif()
   endif()
 
 
@@ -2489,7 +2543,7 @@ elseif(VITA)
       ${SDL2_SOURCE_DIR}/src/thread/vita/SDL_sysmutex.c
       ${SDL2_SOURCE_DIR}/src/thread/vita/SDL_sysmutex.c
       ${SDL2_SOURCE_DIR}/src/thread/vita/SDL_syssem.c
       ${SDL2_SOURCE_DIR}/src/thread/vita/SDL_syssem.c
       ${SDL2_SOURCE_DIR}/src/thread/vita/SDL_systhread.c
       ${SDL2_SOURCE_DIR}/src/thread/vita/SDL_systhread.c
-      ${SDL2_SOURCE_DIR}/src/thread/vita/SDL_syscond.c
+      ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_syscond.c
       ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_systls.c)
       ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_systls.c)
     set(HAVE_SDL_THREADS TRUE)
     set(HAVE_SDL_THREADS TRUE)
   endif()
   endif()
@@ -2641,10 +2695,18 @@ elseif(PSP)
   endif()
   endif()
   if(SDL_THREADS)
   if(SDL_THREADS)
     set(SDL_THREAD_PSP 1)
     set(SDL_THREAD_PSP 1)
-    file(GLOB PSP_THREAD_SOURCES ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_systls.c ${SDL2_SOURCE_DIR}/src/thread/psp/*.c)
+    file(GLOB PSP_THREAD_SOURCES
+      ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_systls.c
+      ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_syscond.c
+      ${SDL2_SOURCE_DIR}/src/thread/psp/*.c)
     list(APPEND SOURCE_FILES ${PSP_THREAD_SOURCES})
     list(APPEND SOURCE_FILES ${PSP_THREAD_SOURCES})
     set(HAVE_SDL_THREADS TRUE)
     set(HAVE_SDL_THREADS TRUE)
   endif()
   endif()
+  if(SDL_LOCALE)
+    file(GLOB PSP_LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/psp/*.c)
+    list(APPEND SOURCE_FILES ${PSP_LOCALE_SOURCES})
+    set(HAVE_SDL_LOCALE TRUE)
+  endif()
   if(SDL_TIMERS)
   if(SDL_TIMERS)
     set(SDL_TIMER_PSP 1)
     set(SDL_TIMER_PSP 1)
     file(GLOB PSP_TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/psp/*.c)
     file(GLOB PSP_TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/psp/*.c)
@@ -2677,7 +2739,6 @@ elseif(PSP)
   endif()
   endif()
 
 
 elseif(PS2)
 elseif(PS2)
-  list(APPEND EXTRA_CFLAGS "-DPS2" "-D__PS2__" "-I$ENV{PS2SDK}/ports/include" "-I$ENV{PS2DEV}/gsKit/include")
 
 
   file(GLOB PS2_MAIN_SOURCES ${SDL2_SOURCE_DIR}/src/main/ps2/*.c)
   file(GLOB PS2_MAIN_SOURCES ${SDL2_SOURCE_DIR}/src/main/ps2/*.c)
   set(SDLMAIN_SOURCES ${SDLMAIN_SOURCES} ${PS2_MAIN_SOURCES})
   set(SDLMAIN_SOURCES ${SDLMAIN_SOURCES} ${PS2_MAIN_SOURCES})
@@ -2702,7 +2763,11 @@ elseif(PS2)
   endif()
   endif()
   if(SDL_THREADS)
   if(SDL_THREADS)
     set(SDL_THREAD_PS2 1)
     set(SDL_THREAD_PS2 1)
-    file(GLOB PS2_THREAD_SOURCES ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_systls.c ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_sysmutex.c ${SDL2_SOURCE_DIR}/src/thread/ps2/*.c)
+    file(GLOB PS2_THREAD_SOURCES
+      ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_systls.c
+      ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_sysmutex.c
+      ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_syscond.c
+      ${SDL2_SOURCE_DIR}/src/thread/ps2/*.c)
     list(APPEND SOURCE_FILES ${PS2_THREAD_SOURCES})
     list(APPEND SOURCE_FILES ${PS2_THREAD_SOURCES})
     set(HAVE_SDL_THREADS TRUE)
     set(HAVE_SDL_THREADS TRUE)
   endif()
   endif()
@@ -2833,7 +2898,9 @@ elseif(N3DS)
   if(SDL_THREADS)
   if(SDL_THREADS)
     set(SDL_THREAD_N3DS 1)
     set(SDL_THREAD_N3DS 1)
     file(GLOB N3DS_THREAD_SOURCES ${SDL2_SOURCE_DIR}/src/thread/n3ds/*.c)
     file(GLOB N3DS_THREAD_SOURCES ${SDL2_SOURCE_DIR}/src/thread/n3ds/*.c)
-    list(APPEND SOURCE_FILES ${N3DS_THREAD_SOURCES} ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_systls.c)
+    list(APPEND SOURCE_FILES ${N3DS_THREAD_SOURCES}
+      ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_systls.c
+      ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_syscond.c)
     set(HAVE_SDL_THREADS TRUE)
     set(HAVE_SDL_THREADS TRUE)
   endif()
   endif()
 
 
@@ -3021,10 +3088,14 @@ endif()
 listtostr(EXTRA_CFLAGS _EXTRA_CFLAGS)
 listtostr(EXTRA_CFLAGS _EXTRA_CFLAGS)
 set(EXTRA_CFLAGS ${_EXTRA_CFLAGS})
 set(EXTRA_CFLAGS ${_EXTRA_CFLAGS})
 
 
+if(USE_GCC OR USE_CLANG)
+  string(REGEX REPLACE "(^| )-I" "\\1 -isystem" EXTRA_CFLAGS "${EXTRA_CFLAGS}")
+endif()
+
 # Compat helpers for the configuration files
 # Compat helpers for the configuration files
 
 
-if(EXISTS "${PROJECT_SOURCE_DIR}/VERSION.txt")
-  file(READ "${PROJECT_SOURCE_DIR}/VERSION.txt" SDL_SOURCE_VERSION)
+if(EXISTS "${PROJECT_SOURCE_DIR}/REVISION.txt")
+  file(READ "${PROJECT_SOURCE_DIR}/REVISION.txt" SDL_SOURCE_VERSION)
   string(STRIP "${SDL_SOURCE_VERSION}" SDL_SOURCE_VERSION)
   string(STRIP "${SDL_SOURCE_VERSION}" SDL_SOURCE_VERSION)
 endif()
 endif()
 
 
@@ -3083,9 +3154,17 @@ else()
   set(sdl_static_libname "SDL2")
   set(sdl_static_libname "SDL2")
 endif()
 endif()
 
 
-set(prefix ${CMAKE_INSTALL_PREFIX})
+# CMAKE_PREFIX_PATH and CMAKE_INSTALL_FULL_BINDIR can be a non-absolute path
+# when a master-project does e.g. `set(CMAKE_INSTALL_PREFIX "libs/SDL2" CACHE PATH "prefix" FORCE)`.
+if(NOT IS_ABSOLUTE "${CMAKE_INSTALL_PREFIX}")
+  set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_PREFIX}")
+endif()
+if(NOT IS_ABSOLUTE "${CMAKE_INSTALL_FULL_BINDIR}")
+  set(CMAKE_INSTALL_FULL_BINDIR "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_FULL_BINDIR}")
+endif()
 file(RELATIVE_PATH bin_prefix_relpath "${CMAKE_INSTALL_FULL_BINDIR}" "${CMAKE_INSTALL_PREFIX}")
 file(RELATIVE_PATH bin_prefix_relpath "${CMAKE_INSTALL_FULL_BINDIR}" "${CMAKE_INSTALL_PREFIX}")
 
 
+set(prefix ${CMAKE_INSTALL_PREFIX})
 set(exec_prefix "\${prefix}")
 set(exec_prefix "\${prefix}")
 set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
 set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
 set(bindir "\${exec_prefix}/${CMAKE_INSTALL_BINDIR}")
 set(bindir "\${exec_prefix}/${CMAKE_INSTALL_BINDIR}")
@@ -3110,7 +3189,7 @@ endif()
 
 
 # Clean up the different lists
 # Clean up the different lists
 listtostr(EXTRA_LIBS _EXTRA_LIBS "-l")
 listtostr(EXTRA_LIBS _EXTRA_LIBS "-l")
-set(SDL_STATIC_LIBS ${SDL_LIBS} ${EXTRA_LDFLAGS} ${_EXTRA_LIBS})
+set(SDL_STATIC_LIBS ${EXTRA_LDFLAGS} ${_EXTRA_LIBS} ${PKGCONFIG_LDFLAGS})
 list(REMOVE_DUPLICATES SDL_STATIC_LIBS)
 list(REMOVE_DUPLICATES SDL_STATIC_LIBS)
 listtostr(SDL_STATIC_LIBS _SDL_STATIC_LIBS)
 listtostr(SDL_STATIC_LIBS _SDL_STATIC_LIBS)
 set(SDL_STATIC_LIBS ${_SDL_STATIC_LIBS})
 set(SDL_STATIC_LIBS ${_SDL_STATIC_LIBS})
@@ -3144,9 +3223,11 @@ macro(check_add_debug_flag FLAG SUFFIX)
         set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FLAG}")
         set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FLAG}")
     endif()
     endif()
 
 
-    check_cxx_compiler_flag(${FLAG} HAS_CXX_${SUFFIX})
-    if (HAS_CXX_${SUFFIX})
-        set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAG}")
+    if(CMAKE_CXX_COMPILER)
+      check_cxx_compiler_flag(${FLAG} HAS_CXX_${SUFFIX})
+      if (HAS_CXX_${SUFFIX})
+          set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAG}")
+      endif()
     endif()
     endif()
 endmacro()
 endmacro()
 
 
@@ -3165,18 +3246,20 @@ macro(asan_check_add_debug_flag2 ASAN_FLAG)
 
 
     set (STORED_REQLIBS ${CMAKE_REQUIRED_LIBRARIES})
     set (STORED_REQLIBS ${CMAKE_REQUIRED_LIBRARIES})
     set (CMAKE_REQUIRED_LIBRARIES "${FLAG};asan")
     set (CMAKE_REQUIRED_LIBRARIES "${FLAG};asan")
-    check_c_compiler_flag (${FLAG} HAS_C_FLAG_${ASAN_FLAG})
-    check_cxx_compiler_flag (${FLAG} HAS_CXX_FLAG_${ASAN_FLAG})
-    set (CMAKE_REQUIRED_LIBRARIES ${STORED_REQLIBS})
 
 
+    check_c_compiler_flag (${FLAG} HAS_C_FLAG_${ASAN_FLAG})
     if (HAS_C_FLAG_${ASAN_FLAG})
     if (HAS_C_FLAG_${ASAN_FLAG})
         set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FLAG}")
         set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FLAG}")
     endif()
     endif()
 
 
-    if (HAS_CXX_${ASAN_FLAG})
-        set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAG}")
+    if(CMAKE_CXX_COMPILER)
+      check_cxx_compiler_flag (${FLAG} HAS_CXX_FLAG_${ASAN_FLAG})
+      if (HAS_CXX_${ASAN_FLAG})
+          set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAG}")
+      endif()
     endif()
     endif()
 
 
+    set (CMAKE_REQUIRED_LIBRARIES ${STORED_REQLIBS})
     if(HAS_C_${ASAN_FLAG} OR HAS_CXX_${ASAN_FLAG})
     if(HAS_C_${ASAN_FLAG} OR HAS_CXX_${ASAN_FLAG})
       set(HAVE_ASAN ON)
       set(HAVE_ASAN ON)
     endif()
     endif()
@@ -3329,6 +3412,12 @@ if(ANDROID)
 endif()
 endif()
 
 
 if(APPLE)
 if(APPLE)
+  cmake_push_check_state(RESET)
+  check_c_compiler_flag(-fobjc-arc COMPILER_SUPPORTS_FOBJC_ARC)
+  cmake_pop_check_state()
+  if(NOT COMPILER_SUPPORTS_FOBJC_ARC)
+    message(FATAL_ERROR "Compiler does not support -fobjc-arc: this is required on Apple platforms")
+  endif()
   target_compile_options(sdl-build-options INTERFACE "-fobjc-arc")
   target_compile_options(sdl-build-options INTERFACE "-fobjc-arc")
 endif()
 endif()
 
 
@@ -3394,7 +3483,7 @@ if(SDL_SHARED)
     set_property(TARGET SDL2 APPEND_STRING PROPERTY STATIC_LIBRARY_FLAGS " /NODEFAULTLIB")
     set_property(TARGET SDL2 APPEND_STRING PROPERTY STATIC_LIBRARY_FLAGS " /NODEFAULTLIB")
   endif()
   endif()
   # FIXME: if CMAKE_VERSION >= 3.13, use target_link_options for EXTRA_LDFLAGS
   # FIXME: if CMAKE_VERSION >= 3.13, use target_link_options for EXTRA_LDFLAGS
-  target_link_libraries(SDL2 PRIVATE ${EXTRA_LIBS} ${EXTRA_LDFLAGS} ${EXTRA_LDFLAGS_BUILD} ${CMAKE_DEPENDS})
+  target_link_libraries(SDL2 PRIVATE ${EXTRA_LIBS} ${EXTRA_LDFLAGS} ${EXTRA_LDFLAGS_BUILD} ${CMAKE_LIBS})
   target_include_directories(SDL2 PUBLIC
   target_include_directories(SDL2 PUBLIC
       "$<BUILD_INTERFACE:${SDL2_BINARY_DIR}/include>"
       "$<BUILD_INTERFACE:${SDL2_BINARY_DIR}/include>"
       "$<BUILD_INTERFACE:${SDL2_BINARY_DIR}/include/SDL2>"
       "$<BUILD_INTERFACE:${SDL2_BINARY_DIR}/include/SDL2>"
@@ -3430,7 +3519,7 @@ if(SDL_STATIC)
   target_compile_definitions(SDL2-static PRIVATE SDL_STATIC_LIB)
   target_compile_definitions(SDL2-static PRIVATE SDL_STATIC_LIB)
   # TODO: Win32 platforms keep the same suffix .lib for import and static
   # TODO: Win32 platforms keep the same suffix .lib for import and static
   # libraries - do we need to consider this?
   # libraries - do we need to consider this?
-  target_link_libraries(SDL2-static PRIVATE ${EXTRA_LIBS} ${EXTRA_LDFLAGS} ${CMAKE_DEPENDS})
+  target_link_libraries(SDL2-static PRIVATE ${EXTRA_LIBS} ${EXTRA_LDFLAGS} ${CMAKE_LIBS})
   target_include_directories(SDL2-static PUBLIC
   target_include_directories(SDL2-static PUBLIC
       "$<BUILD_INTERFACE:${SDL2_BINARY_DIR}/include>"
       "$<BUILD_INTERFACE:${SDL2_BINARY_DIR}/include>"
       "$<BUILD_INTERFACE:${SDL2_BINARY_DIR}/include/SDL2>"
       "$<BUILD_INTERFACE:${SDL2_BINARY_DIR}/include/SDL2>"
@@ -3470,10 +3559,28 @@ if(SDL_TEST)
       "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
       "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
       "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/SDL2>")
       "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/SDL2>")
   target_link_libraries(SDL2_test PRIVATE ${EXTRA_TEST_LIBS})
   target_link_libraries(SDL2_test PRIVATE ${EXTRA_TEST_LIBS})
+  target_include_directories(SDL2_test PRIVATE ${EXTRA_TEST_INCLUDES})
   set_property(TARGET SDL2_test APPEND PROPERTY COMPATIBLE_INTERFACE_STRING "SDL_VERSION")
   set_property(TARGET SDL2_test APPEND PROPERTY COMPATIBLE_INTERFACE_STRING "SDL_VERSION")
   set_property(TARGET SDL2_test PROPERTY INTERFACE_SDL_VERSION "SDL2")
   set_property(TARGET SDL2_test PROPERTY INTERFACE_SDL_VERSION "SDL2")
 endif()
 endif()
 
 
+if(MSVC AND NOT SDL_LIBC)
+  set(targets )
+  if(TARGET SDL2)
+    list(APPEND targets SDL2)
+  endif()
+  if(TARGET SDL2-static)
+    list(APPEND targets SDL2-static)
+  endif()
+  if(TARGET SDL2_test)
+    list(APPEND targets SDL2_test)
+  endif()
+  set_property(TARGET ${targets} APPEND PROPERTY COMPILE_OPTIONS "/GS-;/Gs1048576")
+  if(NOT ARCH_64 AND NOT CMAKE_GENERATOR_PLATFORM STREQUAL "ARM")
+    set_property(TARGET ${targets} APPEND PROPERTY COMPILE_OPTIONS "/arch:SSE")
+  endif()
+endif()
+
 ##### Installation targets #####
 ##### Installation targets #####
 if(NOT SDL2_DISABLE_INSTALL)
 if(NOT SDL2_DISABLE_INSTALL)
   if(SDL_SHARED)
   if(SDL_SHARED)
@@ -3481,6 +3588,9 @@ if(NOT SDL2_DISABLE_INSTALL)
       LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
       LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
       ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
       ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
       RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
       RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
+    if(MSVC)
+      SDL_install_pdb(SDL2 "${CMAKE_INSTALL_BINDIR}")
+    endif()
   endif()
   endif()
 
 
   if(NOT WINDOWS_STORE AND NOT SDL2_DISABLE_SDL2MAIN)
   if(NOT WINDOWS_STORE AND NOT SDL2_DISABLE_SDL2MAIN)
@@ -3488,6 +3598,9 @@ if(NOT SDL2_DISABLE_INSTALL)
       LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
       LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
       ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
       ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
       RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
       RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
+    if(MSVC)
+      SDL_install_pdb(SDL2main "${CMAKE_INSTALL_LIBDIR}")
+    endif()
   endif()
   endif()
 
 
   if(SDL_STATIC)
   if(SDL_STATIC)
@@ -3495,6 +3608,9 @@ if(NOT SDL2_DISABLE_INSTALL)
       LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
       LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
       ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
       ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
       RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
       RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
+    if(MSVC)
+      SDL_install_pdb(SDL2-static "${CMAKE_INSTALL_LIBDIR}")
+    endif()
   endif()
   endif()
 
 
   if(SDL_TEST)
   if(SDL_TEST)
@@ -3502,6 +3618,9 @@ if(NOT SDL2_DISABLE_INSTALL)
       LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
       LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
       ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
       ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
       RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
       RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
+    if(MSVC)
+      SDL_install_pdb(SDL2_test "${CMAKE_INSTALL_LIBDIR}")
+    endif()
   endif()
   endif()
 
 
   ##### Export files #####
   ##### Export files #####

+ 1 - 1
Engine/lib/sdl/LICENSE.txt

@@ -1,4 +1,4 @@
-Copyright (C) 1997-2023 Sam Lantinga <[email protected]>
+Copyright (C) 1997-2025 Sam Lantinga <[email protected]>
   
   
 This software is provided 'as-is', without any express or implied
 This software is provided 'as-is', without any express or implied
 warranty.  In no event will the authors be held liable for any damages
 warranty.  In no event will the authors be held liable for any damages

+ 1 - 1
Engine/lib/sdl/Makefile.in

@@ -52,7 +52,7 @@ WAYLAND_SCANNER_CODE_MODE = @WAYLAND_SCANNER_CODE_MODE@
 
 
 INSTALL_SDL2_CONFIG = @INSTALL_SDL2_CONFIG@
 INSTALL_SDL2_CONFIG = @INSTALL_SDL2_CONFIG@
 
 
-SRC_DIST = *.md *.txt acinclude Android.mk autogen.sh android-project build-scripts cmake cmake_uninstall.cmake.in configure configure.ac docs include Makefile.* mingw sdl2-config.cmake.in sdl2-config-version.cmake.in sdl2-config.in sdl2.m4 sdl2.pc.in SDL2.spec.in SDL2Config.cmake.in src test VisualC VisualC-WinRT Xcode Xcode-iOS wayland-protocols
+SRC_DIST = *.md *.txt acinclude Android.mk autogen.sh android-project build-scripts cmake cmake_uninstall.cmake.in configure configure.ac docs include Makefile.* mingw sdl2-config.cmake.in sdl2-config-version.cmake.in sdl2-config.in sdl2.m4 sdl2.pc.in SDL2.spec.in SDL2Config.cmake.in src test VisualC VisualC-GDK VisualC-WinRT Xcode Xcode-iOS wayland-protocols
 GEN_DIST = SDL2.spec
 GEN_DIST = SDL2.spec
 
 
 ifneq ($V,1)
 ifneq ($V,1)

+ 8 - 6
Engine/lib/sdl/Makefile.os2

@@ -1,4 +1,4 @@
-# Open Watcom makefile to build SDL2.dll for OS/2
+# Open Watcom makefile to build SDL2.dll for OS/2:
 # wmake -f Makefile.os2
 # wmake -f Makefile.os2
 #
 #
 # If you have GNU libiconv installed (iconv2.dll), you
 # If you have GNU libiconv installed (iconv2.dll), you
@@ -14,8 +14,8 @@
 
 
 LIBNAME = SDL2
 LIBNAME = SDL2
 MAJOR_VERSION = 2
 MAJOR_VERSION = 2
-MINOR_VERSION = 28
-MICRO_VERSION = 4
+MINOR_VERSION = 32
+MICRO_VERSION = 6
 VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION)
 VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION)
 DESCRIPTION = Simple DirectMedia Layer 2
 DESCRIPTION = Simple DirectMedia Layer 2
 
 
@@ -56,7 +56,7 @@ CFLAGS_DLL+= -bd
 # iconv:
 # iconv:
 LIBICONV_LIB=iconv2.lib
 LIBICONV_LIB=iconv2.lib
 !ifeq LIBICONV 1
 !ifeq LIBICONV 1
-CFLAGS_DLL+= -DHAVE_ICONV=1 -DHAVE_ICONV_H=1
+CFLAGS_DLL+= -DHAVE_ICONV=1 -DHAVE_ICONV_H=1 -DSDL_USE_LIBICONV
 LIBS+= $(ICONVLIB)
 LIBS+= $(ICONVLIB)
 !else
 !else
 LIBS+= libuls.lib libconv.lib
 LIBS+= libuls.lib libconv.lib
@@ -81,7 +81,7 @@ SRCS+= SDL_events.c SDL_quit.c SDL_keyboard.c SDL_mouse.c SDL_windowevents.c &
        SDL_clipboardevents.c SDL_dropevents.c SDL_displayevents.c SDL_gesture.c &
        SDL_clipboardevents.c SDL_dropevents.c SDL_displayevents.c SDL_gesture.c &
        SDL_sensor.c SDL_touch.c
        SDL_sensor.c SDL_touch.c
 SRCS+= SDL_haptic.c SDL_hidapi.c SDL_gamecontroller.c SDL_joystick.c controller_type.c
 SRCS+= SDL_haptic.c SDL_hidapi.c SDL_gamecontroller.c SDL_joystick.c controller_type.c
-SRCS+= SDL_render.c yuv_rgb.c SDL_yuv.c SDL_yuv_sw.c SDL_blendfillrect.c &
+SRCS+= SDL_render.c yuv_rgb_sse.c yuv_rgb_std.c SDL_yuv.c SDL_yuv_sw.c SDL_blendfillrect.c &
        SDL_blendline.c SDL_blendpoint.c SDL_drawline.c SDL_drawpoint.c &
        SDL_blendline.c SDL_blendpoint.c SDL_drawline.c SDL_drawpoint.c &
        SDL_render_sw.c SDL_rotate.c SDL_triangle.c
        SDL_render_sw.c SDL_rotate.c SDL_triangle.c
 SRCS+= SDL_blit.c SDL_blit_0.c SDL_blit_1.c SDL_blit_A.c SDL_blit_auto.c &
 SRCS+= SDL_blit.c SDL_blit_0.c SDL_blit_1.c SDL_blit_A.c SDL_blit_auto.c &
@@ -94,7 +94,7 @@ SRCS+= SDL_systimer.c
 SRCS+= SDL_sysloadso.c
 SRCS+= SDL_sysloadso.c
 SRCS+= SDL_sysfilesystem.c
 SRCS+= SDL_sysfilesystem.c
 SRCS+= SDL_os2joystick.c SDL_syshaptic.c SDL_sysjoystick.c SDL_virtualjoystick.c
 SRCS+= SDL_os2joystick.c SDL_syshaptic.c SDL_sysjoystick.c SDL_virtualjoystick.c
-SRCS+= SDL_hidapijoystick.c SDL_hidapi_rumble.c SDL_hidapi_combined.c SDL_hidapi_gamecube.c SDL_hidapi_luna.c SDL_hidapi_ps3.c SDL_hidapi_ps4.c SDL_hidapi_ps5.c SDL_hidapi_shield.c SDL_hidapi_stadia.c SDL_hidapi_switch.c SDL_hidapi_wii.c SDL_hidapi_xbox360.c SDL_hidapi_xbox360w.c SDL_hidapi_xboxone.c SDL_hidapi_steam.c
+SRCS+= SDL_hidapijoystick.c SDL_hidapi_rumble.c SDL_hidapi_combined.c SDL_hidapi_gamecube.c SDL_hidapi_luna.c SDL_hidapi_ps3.c SDL_hidapi_ps4.c SDL_hidapi_ps5.c SDL_hidapi_shield.c SDL_hidapi_stadia.c SDL_hidapi_switch.c SDL_hidapi_wii.c SDL_hidapi_xbox360.c SDL_hidapi_xbox360w.c SDL_hidapi_xboxone.c SDL_hidapi_steam.c SDL_hidapi_steamdeck.c SDL_steam_virtual_gamepad.c
 SRCS+= SDL_dummyaudio.c SDL_diskaudio.c
 SRCS+= SDL_dummyaudio.c SDL_diskaudio.c
 SRCS+= SDL_nullvideo.c SDL_nullframebuffer.c SDL_nullevents.c
 SRCS+= SDL_nullvideo.c SDL_nullframebuffer.c SDL_nullevents.c
 SRCS+= SDL_dummysensor.c
 SRCS+= SDL_dummysensor.c
@@ -152,6 +152,8 @@ SDL_blendpoint.obj: SDL_blendpoint.c
     wcc386 $(CFLAGS_DLL) -wcd=200 -fo=$^@ $<
     wcc386 $(CFLAGS_DLL) -wcd=200 -fo=$^@ $<
 SDL_RLEaccel.obj: SDL_RLEaccel.c
 SDL_RLEaccel.obj: SDL_RLEaccel.c
     wcc386 $(CFLAGS_DLL) -wcd=201 -fo=$^@ $<
     wcc386 $(CFLAGS_DLL) -wcd=201 -fo=$^@ $<
+yuv_rgb_sse.obj: yuv_rgb_sse.c
+    wcc386 $(CFLAGS_DLL) -wcd=202 -fo=$^@ $<
 !ifeq HIDAPI 1
 !ifeq HIDAPI 1
 # c99 mode needed because of structs with flexible array members in libusb.h
 # c99 mode needed because of structs with flexible array members in libusb.h
 SDL_hidapi.obj: SDL_hidapi.c
 SDL_hidapi.obj: SDL_hidapi.c

+ 9 - 6
Engine/lib/sdl/Makefile.w32

@@ -1,12 +1,12 @@
-# Open Watcom makefile to build SDL2.dll for Win32
+# Open Watcom makefile to build SDL2.dll for Win32:
 # wmake -f Makefile.w32
 # wmake -f Makefile.w32
 #
 #
 # To error out upon warnings: wmake -f Makefile.w32 ENABLE_WERROR=1
 # To error out upon warnings: wmake -f Makefile.w32 ENABLE_WERROR=1
 
 
 LIBNAME = SDL2
 LIBNAME = SDL2
 MAJOR_VERSION = 2
 MAJOR_VERSION = 2
-MINOR_VERSION = 28
-MICRO_VERSION = 4
+MINOR_VERSION = 32
+MICRO_VERSION = 6
 VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION)
 VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION)
 
 
 LIBHOME = .
 LIBHOME = .
@@ -60,7 +60,7 @@ SRCS+= SDL_events.c SDL_quit.c SDL_keyboard.c SDL_mouse.c SDL_windowevents.c &
        SDL_clipboardevents.c SDL_dropevents.c SDL_displayevents.c SDL_gesture.c &
        SDL_clipboardevents.c SDL_dropevents.c SDL_displayevents.c SDL_gesture.c &
        SDL_sensor.c SDL_touch.c
        SDL_sensor.c SDL_touch.c
 SRCS+= SDL_haptic.c SDL_hidapi.c SDL_gamecontroller.c SDL_joystick.c controller_type.c
 SRCS+= SDL_haptic.c SDL_hidapi.c SDL_gamecontroller.c SDL_joystick.c controller_type.c
-SRCS+= SDL_render.c yuv_rgb.c SDL_yuv.c SDL_yuv_sw.c SDL_blendfillrect.c &
+SRCS+= SDL_render.c yuv_rgb_sse.c yuv_rgb_std.c SDL_yuv.c SDL_yuv_sw.c SDL_blendfillrect.c &
        SDL_blendline.c SDL_blendpoint.c SDL_drawline.c SDL_drawpoint.c &
        SDL_blendline.c SDL_blendpoint.c SDL_drawline.c SDL_drawpoint.c &
        SDL_render_sw.c SDL_rotate.c SDL_triangle.c
        SDL_render_sw.c SDL_rotate.c SDL_triangle.c
 SRCS+= SDL_blit.c SDL_blit_0.c SDL_blit_1.c SDL_blit_A.c SDL_blit_auto.c &
 SRCS+= SDL_blit.c SDL_blit_0.c SDL_blit_1.c SDL_blit_A.c SDL_blit_auto.c &
@@ -73,7 +73,7 @@ SRCS+= SDL_systimer.c
 SRCS+= SDL_sysloadso.c
 SRCS+= SDL_sysloadso.c
 SRCS+= SDL_sysfilesystem.c
 SRCS+= SDL_sysfilesystem.c
 SRCS+= SDL_syshaptic.c SDL_sysjoystick.c SDL_virtualjoystick.c
 SRCS+= SDL_syshaptic.c SDL_sysjoystick.c SDL_virtualjoystick.c
-SRCS+= SDL_hidapijoystick.c SDL_hidapi_rumble.c SDL_hidapi_combined.c SDL_hidapi_gamecube.c SDL_hidapi_luna.c SDL_hidapi_ps3.c SDL_hidapi_ps4.c SDL_hidapi_ps5.c SDL_hidapi_shield.c SDL_hidapi_stadia.c SDL_hidapi_switch.c SDL_hidapi_wii.c SDL_hidapi_xbox360.c SDL_hidapi_xbox360w.c SDL_hidapi_xboxone.c SDL_hidapi_steam.c
+SRCS+= SDL_hidapijoystick.c SDL_hidapi_rumble.c SDL_hidapi_combined.c SDL_hidapi_gamecube.c SDL_hidapi_luna.c SDL_hidapi_ps3.c SDL_hidapi_ps4.c SDL_hidapi_ps5.c SDL_hidapi_shield.c SDL_hidapi_stadia.c SDL_hidapi_switch.c SDL_hidapi_wii.c SDL_hidapi_xbox360.c SDL_hidapi_xbox360w.c SDL_hidapi_xboxone.c SDL_hidapi_steam.c SDL_hidapi_steamdeck.c
 SRCS+= SDL_dummyaudio.c SDL_diskaudio.c
 SRCS+= SDL_dummyaudio.c SDL_diskaudio.c
 SRCS+= SDL_nullvideo.c SDL_nullframebuffer.c SDL_nullevents.c
 SRCS+= SDL_nullvideo.c SDL_nullframebuffer.c SDL_nullevents.c
 SRCS+= SDL_dummysensor.c
 SRCS+= SDL_dummysensor.c
@@ -93,7 +93,7 @@ SRCS+= SDL_render_gl.c SDL_shaders_gl.c
 SRCS+= SDL_render_gles2.c SDL_shaders_gles2.c
 SRCS+= SDL_render_gles2.c SDL_shaders_gles2.c
 SRCS+= SDL_windowssensor.c
 SRCS+= SDL_windowssensor.c
 SRCS+= SDL_syscond_cv.c
 SRCS+= SDL_syscond_cv.c
-SRCS+= SDL_windowsclipboard.c SDL_windowsevents.c SDL_windowsframebuffer.c SDL_windowskeyboard.c SDL_windowsmessagebox.c SDL_windowsmodes.c SDL_windowsmouse.c SDL_windowsopengl.c SDL_windowsopengles.c SDL_windowsshape.c SDL_windowsvideo.c SDL_windowsvulkan.c SDL_windowswindow.c
+SRCS+= SDL_windowsclipboard.c SDL_windowsevents.c SDL_windowsframebuffer.c SDL_windowskeyboard.c SDL_windowsmessagebox.c SDL_windowsmodes.c SDL_windowsmouse.c SDL_windowsopengl.c SDL_windowsopengles.c SDL_windowsshape.c SDL_windowsvideo.c SDL_windowsvulkan.c SDL_windowswindow.c SDL_steam_virtual_gamepad.c
 
 
 SRCS+= SDL_dynapi.c
 SRCS+= SDL_dynapi.c
 
 
@@ -147,6 +147,9 @@ SDL_RLEaccel.obj: SDL_RLEaccel.c
 SDL_malloc.obj: SDL_malloc.c
 SDL_malloc.obj: SDL_malloc.c
     wcc386 $(CFLAGS_DLL) -wcd=201 -fo=$^@ $<
     wcc386 $(CFLAGS_DLL) -wcd=201 -fo=$^@ $<
 
 
+yuv_rgb_sse.obj: yuv_rgb_sse.c
+    wcc386 $(CFLAGS_DLL) -wcd=202 -fo=$^@ $<
+
 # SDL2libm
 # SDL2libm
 MSRCS= e_atan2.c e_exp.c e_fmod.c e_log10.c e_log.c e_pow.c e_rem_pio2.c e_sqrt.c &
 MSRCS= e_atan2.c e_exp.c e_fmod.c e_log10.c e_log.c e_pow.c e_rem_pio2.c e_sqrt.c &
        k_cos.c k_rem_pio2.c k_sin.c k_tan.c &
        k_cos.c k_rem_pio2.c k_sin.c k_tan.c &

+ 0 - 119
Engine/lib/sdl/SDL2.spec

@@ -1,119 +0,0 @@
-Summary: Simple DirectMedia Layer
-Name: SDL2
-Version: 2.28.4
-Release: 2
-Source: http://www.libsdl.org/release/%{name}-%{version}.tar.gz
-URL: http://www.libsdl.org/
-License: zlib
-Group: System Environment/Libraries
-BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot
-Prefix: %{_prefix}
-%ifos linux
-Provides: libSDL2-2.0.so.0
-%endif
-
-%define __defattr %defattr(-,root,root)
-%define __soext so
-
-%description
-This is the Simple DirectMedia Layer, a generic API that provides low
-level access to audio, keyboard, mouse, and display framebuffer across
-multiple platforms.
-
-%package devel
-Summary: Libraries, includes and more to develop SDL applications.
-Group: Development/Libraries
-Requires: %{name} = %{version}
-
-%description devel
-This is the Simple DirectMedia Layer, a generic API that provides low
-level access to audio, keyboard, mouse, and display framebuffer across
-multiple platforms.
-
-This is the libraries, include files and other resources you can use
-to develop SDL applications.
-
-
-%prep
-%setup -q 
-
-%build
-%ifos linux
-CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{prefix} --disable-video-directfb
-%else
-%configure
-%endif
-make
-
-%install
-rm -rf $RPM_BUILD_ROOT
-%ifos linux
-make install prefix=$RPM_BUILD_ROOT%{prefix} \
-             bindir=$RPM_BUILD_ROOT%{_bindir} \
-             libdir=$RPM_BUILD_ROOT%{_libdir} \
-             includedir=$RPM_BUILD_ROOT%{_includedir} \
-             datadir=$RPM_BUILD_ROOT%{_datadir} \
-             mandir=$RPM_BUILD_ROOT%{_mandir}
-%else
-%makeinstall
-%endif
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-%files
-%{__defattr}
-%doc README*.txt LICENSE.txt CREDITS.txt BUGS.txt
-%{_libdir}/lib*.%{__soext}.*
-
-%files devel
-%{__defattr}
-%doc docs/README*.md
-%{_bindir}/*-config
-%{_libdir}/lib*.a
-%{_libdir}/lib*.la
-%{_libdir}/lib*.%{__soext}
-%{_includedir}/*/*.h
-%{_libdir}/cmake/*
-%{_libdir}/pkgconfig/SDL2/*
-%{_datadir}/aclocal/*
-
-%changelog
-* Thu Jun 04 2015 Ryan C. Gordon <[email protected]>
-- Fixed README paths.
-
-* Sun Dec 07 2014 Simone Contini <[email protected]>
-- Fixed changelog date issue and docs filenames
-
-* Sun Jan 22 2012 Sam Lantinga <[email protected]>
-- Updated for SDL 2.0
-
-* Tue May 16 2006 Sam Lantinga <[email protected]>
-- Removed support for Darwin, due to build problems on ps2linux
-
-* Sat Jan 03 2004 Anders Bjorklund <[email protected]>
-- Added support for Darwin, updated spec file
-
-* Wed Jan 19 2000 Sam Lantinga <[email protected]>
-- Re-integrated spec file into SDL distribution
-- 'name' and 'version' come from configure 
-- Some of the documentation is devel specific
-- Removed SMP support from %build - it doesn't work with libtool anyway
-
-* Tue Jan 18 2000 Hakan Tandogan <[email protected]>
-- Hacked Mandrake sdl spec to build 1.1
-
-* Sun Dec 19 1999 John Buswell <[email protected]>
-- Build Release
-
-* Sat Dec 18 1999 John Buswell <[email protected]>
-- Add symlink for libSDL-1.0.so.0 required by sdlbomber
-- Added docs
-
-* Thu Dec 09 1999 Lenny Cartier <[email protected]>
-- v 1.0.0
-
-* Mon Nov  1 1999 Chmouel Boudjnah <[email protected]>
-- First spec file for Mandrake distribution.
-
-# end of file

+ 0 - 1
Engine/lib/sdl/VERSION.txt

@@ -1 +0,0 @@
-release-2.28.4-0-gcc016b004

+ 7 - 0
Engine/lib/sdl/VisualC-GDK/clean.sh

@@ -0,0 +1,7 @@
+#!/bin/sh
+find . -type f \( -name '*.user' -o -name '*.sdf' -o -name '*.ncb' -o -name '*.suo' \) -print -delete
+find . -type f \( -name '*.bmp' -o -name '*.wav' -o -name '*.dat' \) -print -delete
+find . -depth -type d \( -name Gaming.Desktop.x64 \) -exec rm -rv {} \;
+find . -depth -type d \( -name Gaming.Xbox.Scarlett.x64 \) -exec rm -rv {} \;
+find . -depth -type d \( -name Gaming.Xbox.XboxOne.x64 \) -exec rm -rv {} \;
+rm shaders/*.h

BIN
Engine/lib/sdl/VisualC-GDK/logos/Logo100x100.png


BIN
Engine/lib/sdl/VisualC-GDK/logos/Logo150x150.png


BIN
Engine/lib/sdl/VisualC-GDK/logos/Logo44x44.png


BIN
Engine/lib/sdl/VisualC-GDK/logos/Logo480x480.png


BIN
Engine/lib/sdl/VisualC-GDK/logos/SplashScreenImage.png


+ 19 - 0
Engine/lib/sdl/VisualC-GDK/shaders/D3D12_PixelShader_Colors.hlsl

@@ -0,0 +1,19 @@
+struct PixelShaderInput
+{
+    float4 pos : SV_POSITION;
+    float2 tex : TEXCOORD0;
+    float4 color : COLOR0;
+};
+
+#define ColorRS \
+    "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \
+    "DENY_DOMAIN_SHADER_ROOT_ACCESS |" \
+    "DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \
+    "DENY_HULL_SHADER_ROOT_ACCESS )," \
+    "RootConstants(num32BitConstants=32, b0)"
+
+[RootSignature(ColorRS)]
+float4 main(PixelShaderInput input) : SV_TARGET0
+{
+    return input.color;
+}

+ 43 - 0
Engine/lib/sdl/VisualC-GDK/shaders/D3D12_PixelShader_NV12_BT601.hlsl

@@ -0,0 +1,43 @@
+Texture2D theTextureY : register(t0);
+Texture2D theTextureUV : register(t1);
+SamplerState theSampler : register(s0);
+
+struct PixelShaderInput
+{
+    float4 pos : SV_POSITION;
+    float2 tex : TEXCOORD0;
+    float4 color : COLOR0;
+};
+
+#define NVRS \
+    "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \
+    "            DENY_DOMAIN_SHADER_ROOT_ACCESS |" \
+    "            DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \
+    "            DENY_HULL_SHADER_ROOT_ACCESS )," \
+    "RootConstants(num32BitConstants=32, b0),"\
+    "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )"
+
+[RootSignature(NVRS)]
+float4 main(PixelShaderInput input) : SV_TARGET
+{
+    const float3 offset = {-0.0627451017, -0.501960814, -0.501960814};
+    const float3 Rcoeff = {1.1644,  0.0000,  1.5960};
+    const float3 Gcoeff = {1.1644, -0.3918, -0.8130};
+    const float3 Bcoeff = {1.1644,  2.0172,  0.0000};
+
+    float4 Output;
+
+    float3 yuv;
+    yuv.x = theTextureY.Sample(theSampler, input.tex).r;
+    yuv.yz = theTextureUV.Sample(theSampler, input.tex).rg;
+
+    yuv += offset;
+    Output.r = dot(yuv, Rcoeff);
+    Output.g = dot(yuv, Gcoeff);
+    Output.b = dot(yuv, Bcoeff);
+    Output.a = 1.0f;
+
+    return Output * input.color;
+}

+ 43 - 0
Engine/lib/sdl/VisualC-GDK/shaders/D3D12_PixelShader_NV12_BT709.hlsl

@@ -0,0 +1,43 @@
+Texture2D theTextureY : register(t0);
+Texture2D theTextureUV : register(t1);
+SamplerState theSampler : register(s0);
+
+struct PixelShaderInput
+{
+    float4 pos : SV_POSITION;
+    float2 tex : TEXCOORD0;
+    float4 color : COLOR0;
+};
+
+#define NVRS \
+    "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \
+    "            DENY_DOMAIN_SHADER_ROOT_ACCESS |" \
+    "            DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \
+    "            DENY_HULL_SHADER_ROOT_ACCESS )," \
+    "RootConstants(num32BitConstants=32, b0),"\
+    "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )"
+
+[RootSignature(NVRS)]
+float4 main(PixelShaderInput input) : SV_TARGET
+{
+    const float3 offset = {-0.0627451017, -0.501960814, -0.501960814};
+    const float3 Rcoeff = {1.1644,  0.0000,  1.7927};
+    const float3 Gcoeff = {1.1644, -0.2132, -0.5329};
+    const float3 Bcoeff = {1.1644,  2.1124,  0.0000};
+
+    float4 Output;
+
+    float3 yuv;
+    yuv.x = theTextureY.Sample(theSampler, input.tex).r;
+    yuv.yz = theTextureUV.Sample(theSampler, input.tex).rg;
+
+    yuv += offset;
+    Output.r = dot(yuv, Rcoeff);
+    Output.g = dot(yuv, Gcoeff);
+    Output.b = dot(yuv, Bcoeff);
+    Output.a = 1.0f;
+
+    return Output * input.color;
+}

+ 43 - 0
Engine/lib/sdl/VisualC-GDK/shaders/D3D12_PixelShader_NV12_JPEG.hlsl

@@ -0,0 +1,43 @@
+Texture2D theTextureY : register(t0);
+Texture2D theTextureUV : register(t1);
+SamplerState theSampler : register(s0);
+
+struct PixelShaderInput
+{
+    float4 pos : SV_POSITION;
+    float2 tex : TEXCOORD0;
+    float4 color : COLOR0;
+};
+
+#define NVRS \
+    "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \
+    "            DENY_DOMAIN_SHADER_ROOT_ACCESS |" \
+    "            DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \
+    "            DENY_HULL_SHADER_ROOT_ACCESS )," \
+    "RootConstants(num32BitConstants=32, b0),"\
+    "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )"
+
+[RootSignature(NVRS)]
+float4 main(PixelShaderInput input) : SV_TARGET
+{
+    const float3 offset = {0.0, -0.501960814, -0.501960814};
+    const float3 Rcoeff = {1.0000,  0.0000,  1.4020};
+    const float3 Gcoeff = {1.0000, -0.3441, -0.7141};
+    const float3 Bcoeff = {1.0000,  1.7720,  0.0000};
+
+    float4 Output;
+
+    float3 yuv;
+    yuv.x = theTextureY.Sample(theSampler, input.tex).r;
+    yuv.yz = theTextureUV.Sample(theSampler, input.tex).rg;
+
+    yuv += offset;
+    Output.r = dot(yuv, Rcoeff);
+    Output.g = dot(yuv, Gcoeff);
+    Output.b = dot(yuv, Bcoeff);
+    Output.a = 1.0f;
+
+    return Output * input.color;
+}

+ 43 - 0
Engine/lib/sdl/VisualC-GDK/shaders/D3D12_PixelShader_NV21_BT601.hlsl

@@ -0,0 +1,43 @@
+Texture2D theTextureY : register(t0);
+Texture2D theTextureUV : register(t1);
+SamplerState theSampler : register(s0);
+
+struct PixelShaderInput
+{
+    float4 pos : SV_POSITION;
+    float2 tex : TEXCOORD0;
+    float4 color : COLOR0;
+};
+
+#define NVRS \
+    "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \
+    "            DENY_DOMAIN_SHADER_ROOT_ACCESS |" \
+    "            DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \
+    "            DENY_HULL_SHADER_ROOT_ACCESS )," \
+    "RootConstants(num32BitConstants=32, b0),"\
+    "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )"
+
+[RootSignature(NVRS)]
+float4 main(PixelShaderInput input) : SV_TARGET
+{
+    const float3 offset = {-0.0627451017, -0.501960814, -0.501960814};
+    const float3 Rcoeff = {1.1644,  0.0000,  1.5960};
+    const float3 Gcoeff = {1.1644, -0.3918, -0.8130};
+    const float3 Bcoeff = {1.1644,  2.0172,  0.0000};
+
+    float4 Output;
+
+    float3 yuv;
+    yuv.x = theTextureY.Sample(theSampler, input.tex).r;
+    yuv.yz = theTextureUV.Sample(theSampler, input.tex).gr;
+
+    yuv += offset;
+    Output.r = dot(yuv, Rcoeff);
+    Output.g = dot(yuv, Gcoeff);
+    Output.b = dot(yuv, Bcoeff);
+    Output.a = 1.0f;
+
+    return Output * input.color;
+}

+ 43 - 0
Engine/lib/sdl/VisualC-GDK/shaders/D3D12_PixelShader_NV21_BT709.hlsl

@@ -0,0 +1,43 @@
+Texture2D theTextureY : register(t0);
+Texture2D theTextureUV : register(t1);
+SamplerState theSampler : register(s0);
+
+struct PixelShaderInput
+{
+    float4 pos : SV_POSITION;
+    float2 tex : TEXCOORD0;
+    float4 color : COLOR0;
+};
+
+#define NVRS \
+    "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \
+    "            DENY_DOMAIN_SHADER_ROOT_ACCESS |" \
+    "            DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \
+    "            DENY_HULL_SHADER_ROOT_ACCESS )," \
+    "RootConstants(num32BitConstants=32, b0),"\
+    "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )"
+
+[RootSignature(NVRS)]
+float4 main(PixelShaderInput input) : SV_TARGET
+{
+    const float3 offset = {-0.0627451017, -0.501960814, -0.501960814};
+    const float3 Rcoeff = {1.1644,  0.0000,  1.7927};
+    const float3 Gcoeff = {1.1644, -0.2132, -0.5329};
+    const float3 Bcoeff = {1.1644,  2.1124,  0.0000};
+
+    float4 Output;
+
+    float3 yuv;
+    yuv.x = theTextureY.Sample(theSampler, input.tex).r;
+    yuv.yz = theTextureUV.Sample(theSampler, input.tex).gr;
+
+    yuv += offset;
+    Output.r = dot(yuv, Rcoeff);
+    Output.g = dot(yuv, Gcoeff);
+    Output.b = dot(yuv, Bcoeff);
+    Output.a = 1.0f;
+
+    return Output * input.color;
+}

+ 43 - 0
Engine/lib/sdl/VisualC-GDK/shaders/D3D12_PixelShader_NV21_JPEG.hlsl

@@ -0,0 +1,43 @@
+Texture2D theTextureY : register(t0);
+Texture2D theTextureUV : register(t1);
+SamplerState theSampler : register(s0);
+
+struct PixelShaderInput
+{
+    float4 pos : SV_POSITION;
+    float2 tex : TEXCOORD0;
+    float4 color : COLOR0;
+};
+
+#define NVRS \
+    "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \
+    "            DENY_DOMAIN_SHADER_ROOT_ACCESS |" \
+    "            DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \
+    "            DENY_HULL_SHADER_ROOT_ACCESS )," \
+    "RootConstants(num32BitConstants=32, b0),"\
+    "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )"
+
+[RootSignature(NVRS)]
+float4 main(PixelShaderInput input) : SV_TARGET
+{
+    const float3 offset = {0.0, -0.501960814, -0.501960814};
+    const float3 Rcoeff = {1.0000,  0.0000,  1.4020};
+    const float3 Gcoeff = {1.0000, -0.3441, -0.7141};
+    const float3 Bcoeff = {1.0000,  1.7720,  0.0000};
+
+    float4 Output;
+
+    float3 yuv;
+    yuv.x = theTextureY.Sample(theSampler, input.tex).r;
+    yuv.yz = theTextureUV.Sample(theSampler, input.tex).gr;
+
+    yuv += offset;
+    Output.r = dot(yuv, Rcoeff);
+    Output.g = dot(yuv, Gcoeff);
+    Output.b = dot(yuv, Bcoeff);
+    Output.a = 1.0f;
+
+    return Output * input.color;
+}

+ 24 - 0
Engine/lib/sdl/VisualC-GDK/shaders/D3D12_PixelShader_Textures.hlsl

@@ -0,0 +1,24 @@
+Texture2D theTexture : register(t0);
+SamplerState theSampler : register(s0);
+
+struct PixelShaderInput
+{
+    float4 pos : SV_POSITION;
+    float2 tex : TEXCOORD0;
+    float4 color : COLOR0;
+};
+
+#define TextureRS \
+    "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \
+    "            DENY_DOMAIN_SHADER_ROOT_ACCESS |" \
+    "            DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \
+    "            DENY_HULL_SHADER_ROOT_ACCESS )," \
+    "RootConstants(num32BitConstants=32, b0),"\
+    "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )"
+
+[RootSignature(TextureRS)]
+float4 main(PixelShaderInput input) : SV_TARGET
+{
+    return theTexture.Sample(theSampler, input.tex) * input.color;
+}

+ 46 - 0
Engine/lib/sdl/VisualC-GDK/shaders/D3D12_PixelShader_YUV_BT601.hlsl

@@ -0,0 +1,46 @@
+Texture2D theTextureY : register(t0);
+Texture2D theTextureU : register(t1);
+Texture2D theTextureV : register(t2);
+SamplerState theSampler : register(s0);
+
+struct PixelShaderInput
+{
+    float4 pos : SV_POSITION;
+    float2 tex : TEXCOORD0;
+    float4 color : COLOR0;
+};
+
+#define YUVRS \
+    "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \
+    "            DENY_DOMAIN_SHADER_ROOT_ACCESS |" \
+    "            DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \
+    "            DENY_HULL_SHADER_ROOT_ACCESS )," \
+    "RootConstants(num32BitConstants=32, b0),"\
+    "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( SRV(t2), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )"
+
+[RootSignature(YUVRS)]
+float4 main(PixelShaderInput input) : SV_TARGET
+{
+    const float3 offset = {-0.0627451017, -0.501960814, -0.501960814};
+    const float3 Rcoeff = {1.1644,  0.0000,  1.5960};
+    const float3 Gcoeff = {1.1644, -0.3918, -0.8130};
+    const float3 Bcoeff = {1.1644,  2.0172,  0.0000};
+
+    float4 Output;
+
+    float3 yuv;
+    yuv.x = theTextureY.Sample(theSampler, input.tex).r;
+    yuv.y = theTextureU.Sample(theSampler, input.tex).r;
+    yuv.z = theTextureV.Sample(theSampler, input.tex).r;
+
+    yuv += offset;
+    Output.r = dot(yuv, Rcoeff);
+    Output.g = dot(yuv, Gcoeff);
+    Output.b = dot(yuv, Bcoeff);
+    Output.a = 1.0f;
+
+    return Output * input.color;
+}

+ 46 - 0
Engine/lib/sdl/VisualC-GDK/shaders/D3D12_PixelShader_YUV_BT709.hlsl

@@ -0,0 +1,46 @@
+Texture2D theTextureY : register(t0);
+Texture2D theTextureU : register(t1);
+Texture2D theTextureV : register(t2);
+SamplerState theSampler : register(s0);
+
+struct PixelShaderInput
+{
+    float4 pos : SV_POSITION;
+    float2 tex : TEXCOORD0;
+    float4 color : COLOR0;
+};
+
+#define YUVRS \
+    "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \
+    "            DENY_DOMAIN_SHADER_ROOT_ACCESS |" \
+    "            DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \
+    "            DENY_HULL_SHADER_ROOT_ACCESS )," \
+    "RootConstants(num32BitConstants=32, b0),"\
+    "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( SRV(t2), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )"
+
+[RootSignature(YUVRS)]
+float4 main(PixelShaderInput input) : SV_TARGET
+{
+    const float3 offset = {-0.0627451017, -0.501960814, -0.501960814};
+    const float3 Rcoeff = {1.1644,  0.0000,  1.7927};
+    const float3 Gcoeff = {1.1644, -0.2132, -0.5329};
+    const float3 Bcoeff = {1.1644,  2.1124,  0.0000};
+
+    float4 Output;
+
+    float3 yuv;
+    yuv.x = theTextureY.Sample(theSampler, input.tex).r;
+    yuv.y = theTextureU.Sample(theSampler, input.tex).r;
+    yuv.z = theTextureV.Sample(theSampler, input.tex).r;
+
+    yuv += offset;
+    Output.r = dot(yuv, Rcoeff);
+    Output.g = dot(yuv, Gcoeff);
+    Output.b = dot(yuv, Bcoeff);
+    Output.a = 1.0f;
+
+    return Output * input.color;
+}

+ 46 - 0
Engine/lib/sdl/VisualC-GDK/shaders/D3D12_PixelShader_YUV_JPEG.hlsl

@@ -0,0 +1,46 @@
+Texture2D theTextureY : register(t0);
+Texture2D theTextureU : register(t1);
+Texture2D theTextureV : register(t2);
+SamplerState theSampler : register(s0);
+
+struct PixelShaderInput
+{
+    float4 pos : SV_POSITION;
+    float2 tex : TEXCOORD0;
+    float4 color : COLOR0;
+};
+
+#define YUVRS \
+    "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \
+    "            DENY_DOMAIN_SHADER_ROOT_ACCESS |" \
+    "            DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \
+    "            DENY_HULL_SHADER_ROOT_ACCESS )," \
+    "RootConstants(num32BitConstants=32, b0),"\
+    "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( SRV(t2), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )"
+
+[RootSignature(YUVRS)]
+float4 main(PixelShaderInput input) : SV_TARGET
+{
+    const float3 offset = {0.0, -0.501960814, -0.501960814};
+    const float3 Rcoeff = {1.0000,  0.0000,  1.4020};
+    const float3 Gcoeff = {1.0000, -0.3441, -0.7141};
+    const float3 Bcoeff = {1.0000,  1.7720,  0.0000};
+
+    float4 Output;
+
+    float3 yuv;
+    yuv.x = theTextureY.Sample(theSampler, input.tex).r;
+    yuv.y = theTextureU.Sample(theSampler, input.tex).r;
+    yuv.z = theTextureV.Sample(theSampler, input.tex).r;
+
+    yuv += offset;
+    Output.r = dot(yuv, Rcoeff);
+    Output.g = dot(yuv, Gcoeff);
+    Output.b = dot(yuv, Bcoeff);
+    Output.a = 1.0f;
+
+    return Output * input.color;
+}

+ 95 - 0
Engine/lib/sdl/VisualC-GDK/shaders/D3D12_VertexShader.hlsl

@@ -0,0 +1,95 @@
+#pragma pack_matrix( row_major )
+
+struct VertexShaderConstants
+{
+    matrix model;
+    matrix projectionAndView;
+};
+ConstantBuffer<VertexShaderConstants> Constants : register(b0);
+
+struct VertexShaderInput
+{
+    float3 pos : POSITION;
+    float2 tex : TEXCOORD0;
+    float4 color : COLOR0;
+};
+
+struct VertexShaderOutput
+{
+    float4 pos : SV_POSITION;
+    float2 tex : TEXCOORD0;
+    float4 color : COLOR0;
+};
+
+#define ColorRS \
+    "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \
+    "DENY_DOMAIN_SHADER_ROOT_ACCESS |" \
+    "DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \
+    "DENY_HULL_SHADER_ROOT_ACCESS )," \
+    "RootConstants(num32BitConstants=32, b0)"
+
+#define TextureRS \
+    "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \
+    "            DENY_DOMAIN_SHADER_ROOT_ACCESS |" \
+    "            DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \
+    "            DENY_HULL_SHADER_ROOT_ACCESS )," \
+    "RootConstants(num32BitConstants=32, b0),"\
+    "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )"
+
+#define YUVRS \
+    "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \
+    "            DENY_DOMAIN_SHADER_ROOT_ACCESS |" \
+    "            DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \
+    "            DENY_HULL_SHADER_ROOT_ACCESS )," \
+    "RootConstants(num32BitConstants=32, b0),"\
+    "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( SRV(t2), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )"
+
+#define NVRS \
+    "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \
+    "            DENY_DOMAIN_SHADER_ROOT_ACCESS |" \
+    "            DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \
+    "            DENY_HULL_SHADER_ROOT_ACCESS )," \
+    "RootConstants(num32BitConstants=32, b0),"\
+    "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\
+    "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )"
+
+[RootSignature(ColorRS)]
+VertexShaderOutput mainColor(VertexShaderInput input)
+{
+    VertexShaderOutput output;
+    float4 pos = float4(input.pos, 1.0f);
+
+    // Transform the vertex position into projected space.
+    pos = mul(pos, Constants.model);
+    pos = mul(pos, Constants.projectionAndView);
+    output.pos = pos;
+
+    // Pass through texture coordinates and color values without transformation
+    output.tex = input.tex;
+    output.color = input.color;
+
+    return output;
+}
+
+[RootSignature(TextureRS)]
+VertexShaderOutput mainTexture(VertexShaderInput input)
+{
+    return mainColor(input);
+}
+
+[RootSignature(YUVRS)]
+VertexShaderOutput mainYUV(VertexShaderInput input)
+{
+    return mainColor(input);
+}
+
+[RootSignature(NVRS)]
+VertexShaderOutput mainNV(VertexShaderInput input)
+{
+    return mainColor(input);
+}

+ 35 - 0
Engine/lib/sdl/VisualC-GDK/shaders/buildshaders.bat

@@ -0,0 +1,35 @@
+if %2.==one. goto setxboxone
+rem Xbox Series compile
+set XBOXDXC="%GameDKLatest%\GXDK\bin\Scarlett\DXC.exe"
+set SUFFIX=_Series.h
+goto startbuild
+
+:setxboxone
+set XBOXDXC="%GameDKLatest%\GXDK\bin\XboxOne\DXC.exe"
+set SUFFIX=_One.h
+
+:startbuild
+echo Building with %XBOXDXC%
+cd "%1\shaders"
+rem Root Signatures
+%XBOXDXC% -E ColorRS -T rootsig_1_1 -rootsig-define ColorRS -Fh D3D12_RootSig_Color%SUFFIX% -Vn D3D12_RootSig_Color D3D12_VertexShader.hlsl
+%XBOXDXC% -E TextureRS -T rootsig_1_1 -rootsig-define TextureRS -Fh D3D12_RootSig_Texture%SUFFIX% -Vn D3D12_RootSig_Texture D3D12_VertexShader.hlsl
+%XBOXDXC% -E YUVRS -T rootsig_1_1 -rootsig-define YUVRS -Fh D3D12_RootSig_YUV%SUFFIX% -Vn D3D12_RootSig_YUV D3D12_VertexShader.hlsl
+%XBOXDXC% -E NVRS -T rootsig_1_1 -rootsig-define NVRS -Fh D3D12_RootSig_NV%SUFFIX% -Vn D3D12_RootSig_NV D3D12_VertexShader.hlsl
+rem Vertex Shaders
+%XBOXDXC% -E mainColor -T vs_6_0 -Fh D3D12_VertexShader_Color%SUFFIX% -Vn D3D12_VertexShader_Color D3D12_VertexShader.hlsl
+%XBOXDXC% -E mainTexture -T vs_6_0 -Fh D3D12_VertexShader_Texture%SUFFIX% -Vn D3D12_VertexShader_Texture D3D12_VertexShader.hlsl
+%XBOXDXC% -E mainNV -T vs_6_0 -Fh D3D12_VertexShader_NV%SUFFIX% -Vn D3D12_VertexShader_NV D3D12_VertexShader.hlsl
+%XBOXDXC% -E mainYUV -T vs_6_0 -Fh D3D12_VertexShader_YUV%SUFFIX% -Vn D3D12_VertexShader_YUV D3D12_VertexShader.hlsl
+rem Pixel Shaders
+%XBOXDXC% -E main -T ps_6_0 -Fh D3D12_PixelShader_Colors%SUFFIX% -Vn D3D12_PixelShader_Colors D3D12_PixelShader_Colors.hlsl
+%XBOXDXC% -E main -T ps_6_0 -Fh D3D12_PixelShader_NV12_BT601%SUFFIX% -Vn D3D12_PixelShader_NV12_BT601 D3D12_PixelShader_NV12_BT601.hlsl
+%XBOXDXC% -E main -T ps_6_0 -Fh D3D12_PixelShader_NV12_BT709%SUFFIX% -Vn D3D12_PixelShader_NV12_BT709 D3D12_PixelShader_NV12_BT709.hlsl
+%XBOXDXC% -E main -T ps_6_0 -Fh D3D12_PixelShader_NV12_JPEG%SUFFIX% -Vn D3D12_PixelShader_NV12_JPEG D3D12_PixelShader_NV12_JPEG.hlsl
+%XBOXDXC% -E main -T ps_6_0 -Fh D3D12_PixelShader_NV21_BT601%SUFFIX% -Vn D3D12_PixelShader_NV21_BT601 D3D12_PixelShader_NV21_BT601.hlsl
+%XBOXDXC% -E main -T ps_6_0 -Fh D3D12_PixelShader_NV21_BT709%SUFFIX% -Vn D3D12_PixelShader_NV21_BT709 D3D12_PixelShader_NV21_BT709.hlsl
+%XBOXDXC% -E main -T ps_6_0 -Fh D3D12_PixelShader_NV21_JPEG%SUFFIX% -Vn D3D12_PixelShader_NV21_JPEG D3D12_PixelShader_NV21_JPEG.hlsl
+%XBOXDXC% -E main -T ps_6_0 -Fh D3D12_PixelShader_Textures%SUFFIX% -Vn D3D12_PixelShader_Textures D3D12_PixelShader_Textures.hlsl
+%XBOXDXC% -E main -T ps_6_0 -Fh D3D12_PixelShader_YUV_BT601%SUFFIX% -Vn D3D12_PixelShader_YUV_BT601 D3D12_PixelShader_YUV_BT601.hlsl
+%XBOXDXC% -E main -T ps_6_0 -Fh D3D12_PixelShader_YUV_BT709%SUFFIX% -Vn D3D12_PixelShader_YUV_BT709 D3D12_PixelShader_YUV_BT709.hlsl
+%XBOXDXC% -E main -T ps_6_0 -Fh D3D12_PixelShader_YUV_JPEG%SUFFIX% -Vn D3D12_PixelShader_YUV_JPEG D3D12_PixelShader_YUV_JPEG.hlsl

+ 9 - 0
Engine/lib/sdl/VisualC-GDK/tests/testgamecontroller/PackageLayout.xml

@@ -0,0 +1,9 @@
+<Package>
+  <Chunk Id="1000" Marker="Launch">
+    <FileGroup DestinationPath="." SourcePath="." Include="testgamecontroller.exe" />
+    <FileGroup DestinationPath="." SourcePath="." Include="MicrosoftGame.config" />
+    <FileGroup DestinationPath="." SourcePath="." Include="*.bmp" />
+    <FileGroup DestinationPath="." SourcePath="." Include="*.png" />
+    <FileGroup DestinationPath="." SourcePath="." Include="*.dll" />
+  </Chunk>
+</Package>

+ 34 - 0
Engine/lib/sdl/VisualC-GDK/tests/testgamecontroller/wingdk/MicrosoftGame.config

@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Game configVersion="1">
+
+	<!-- Set these to the correct identifiers from Partner Center -->
+	<Identity Name="SDL"
+		Version="1.0.0.0"
+		Publisher="CN=Publisher"/>
+
+	<ExecutableList>
+		<Executable Name="testgamecontroller.exe"
+					TargetDeviceFamily="PC"
+					Id="Game" />
+	</ExecutableList>
+
+	<DesktopRegistration>
+		<DependencyList>
+			<KnownDependency Name="VC14"/>
+		</DependencyList>
+	</DesktopRegistration>
+
+	<!-- Set these to the correct values from Partner Center -->
+	<MSAAppId>PleaseChangeMe</MSAAppId>
+	<TitleId>FFFFFFFF</TitleId>
+
+	<ShellVisuals DefaultDisplayName="testgamecontroller"
+					PublisherDisplayName="SDL"
+					Square480x480Logo="Logo480x480.png"
+					Square150x150Logo="Logo150x150.png"
+					Square44x44Logo="Logo44x44.png"
+					Description="testgamecontroller"
+					ForegroundText="light"
+					BackgroundColor="#000000"
+					StoreLogo="Logo100x100.png"/>
+</Game>

+ 29 - 0
Engine/lib/sdl/VisualC-GDK/tests/testgamecontroller/xboxone/MicrosoftGame.config

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Game configVersion="1">
+
+	<!-- Set these to the correct identifiers from Partner Center -->
+	<Identity Name="SDL"
+		Version="1.0.0.0"
+		Publisher="CN=Publisher"/>
+
+	<ExecutableList>
+		<Executable Name="testgamecontroller.exe"
+					TargetDeviceFamily="XboxOne"
+					Id="Game" />
+	</ExecutableList>
+
+	<!-- Set these to the correct values from Partner Center -->
+	<MSAAppId>PleaseChangeMe</MSAAppId>
+	<TitleId>FFFFFFFF</TitleId>
+
+	<ShellVisuals DefaultDisplayName="testgamecontroller"
+					PublisherDisplayName="SDL"
+					Square480x480Logo="Logo480x480.png"
+					Square150x150Logo="Logo150x150.png"
+					Square44x44Logo="Logo44x44.png"
+					SplashScreenImage="SplashScreenImage.png"
+					Description="testgamecontroller"
+					ForegroundText="light"
+					BackgroundColor="#000000"
+					StoreLogo="Logo100x100.png"/>
+</Game>

+ 29 - 0
Engine/lib/sdl/VisualC-GDK/tests/testgamecontroller/xboxseries/MicrosoftGame.config

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Game configVersion="1">
+
+	<!-- Set these to the correct identifiers from Partner Center -->
+	<Identity Name="SDL"
+		Version="1.0.0.0"
+		Publisher="CN=Publisher"/>
+
+	<ExecutableList>
+		<Executable Name="testgamecontroller.exe"
+					TargetDeviceFamily="Scarlett"
+					Id="Game" />
+	</ExecutableList>
+
+	<!-- Set these to the correct values from Partner Center -->
+	<MSAAppId>PleaseChangeMe</MSAAppId>
+	<TitleId>FFFFFFFF</TitleId>
+
+	<ShellVisuals DefaultDisplayName="testgamecontroller"
+					PublisherDisplayName="SDL"
+					Square480x480Logo="Logo480x480.png"
+					Square150x150Logo="Logo150x150.png"
+					Square44x44Logo="Logo44x44.png"
+					SplashScreenImage="SplashScreenImage.png"
+					Description="testgamecontroller"
+					ForegroundText="light"
+					BackgroundColor="#000000"
+					StoreLogo="Logo100x100.png"/>
+</Game>

+ 10 - 0
Engine/lib/sdl/VisualC-GDK/tests/testgdk/PackageLayout.xml

@@ -0,0 +1,10 @@
+<Package>
+  <Chunk Id="1000" Marker="Launch">
+    <FileGroup DestinationPath="." SourcePath="." Include="testgdk.exe" />
+    <FileGroup DestinationPath="." SourcePath="." Include="MicrosoftGame.config" />
+    <FileGroup DestinationPath="." SourcePath="." Include="*.bmp" />
+    <FileGroup DestinationPath="." SourcePath="." Include="*.wav" />
+    <FileGroup DestinationPath="." SourcePath="." Include="*.png" />
+    <FileGroup DestinationPath="." SourcePath="." Include="*.dll" />
+  </Chunk>
+</Package>

+ 503 - 0
Engine/lib/sdl/VisualC-GDK/tests/testgdk/src/testgdk.cpp

@@ -0,0 +1,503 @@
+/*
+  Copyright (C) 1997-2025 Sam Lantinga <[email protected]>
+
+  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.
+*/
+/* testgdk:  Basic tests of using task queue/xbl (with simple drawing) in GDK.
+ * NOTE: As of June 2022 GDK, login will only work if MicrosoftGame.config is
+ * configured properly. See README-gdk.md.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+
+#include "SDL_test.h"
+#include "SDL_test_common.h"
+#include "../src/core/windows/SDL_windows.h"
+
+extern "C" {
+#include "../test/testutils.h"
+}
+
+#include <XGameRuntime.h>
+
+#define NUM_SPRITES    100
+#define MAX_SPEED     1
+
+static SDLTest_CommonState *state;
+static int num_sprites;
+static SDL_Texture **sprites;
+static SDL_bool cycle_color;
+static SDL_bool cycle_alpha;
+static int cycle_direction = 1;
+static int current_alpha = 0;
+static int current_color = 0;
+static int sprite_w, sprite_h;
+static SDL_BlendMode blendMode = SDL_BLENDMODE_BLEND;
+
+int done;
+
+static struct
+{
+    SDL_AudioSpec spec;
+    Uint8 *sound;    /* Pointer to wave data */
+    Uint32 soundlen; /* Length of wave data */
+    int soundpos;    /* Current play position */
+} wave;
+
+static SDL_AudioDeviceID device;
+
+static void
+close_audio()
+{
+    if (device != 0) {
+        SDL_CloseAudioDevice(device);
+        device = 0;
+    }
+}
+
+/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
+static void
+quit(int rc)
+{
+    SDL_free(sprites);
+    close_audio();
+    SDL_FreeWAV(wave.sound);
+    SDLTest_CommonQuit(state);
+    /* If rc is 0, just let main return normally rather than calling exit.
+     * This allows testing of platforms where SDL_main is required and does meaningful cleanup.
+     */
+    if (rc != 0) {
+        exit(rc);
+    }
+}
+
+static void
+open_audio()
+{
+    /* Initialize fillerup() variables */
+    device = SDL_OpenAudioDevice(NULL, SDL_FALSE, &wave.spec, NULL, 0);
+    if (!device) {
+        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open audio: %s\n", SDL_GetError());
+        SDL_FreeWAV(wave.sound);
+        quit(2);
+    }
+
+    /* Let the audio run */
+    SDL_PauseAudioDevice(device, SDL_FALSE);
+}
+
+static void
+reopen_audio()
+{
+    close_audio();
+    open_audio();
+}
+
+void SDLCALL
+fillerup(void *unused, Uint8 *stream, int len)
+{
+    Uint8 *waveptr;
+    int waveleft;
+
+    /* Set up the pointers */
+    waveptr = wave.sound + wave.soundpos;
+    waveleft = wave.soundlen - wave.soundpos;
+
+    /* Go! */
+    while (waveleft <= len) {
+        SDL_memcpy(stream, waveptr, waveleft);
+        stream += waveleft;
+        len -= waveleft;
+        waveptr = wave.sound;
+        waveleft = wave.soundlen;
+        wave.soundpos = 0;
+    }
+    SDL_memcpy(stream, waveptr, len);
+    wave.soundpos += len;
+}
+
+void
+UserLoggedIn(XUserHandle user)
+{
+    HRESULT hr;
+    char gamertag[128];
+    hr = XUserGetGamertag(user, XUserGamertagComponent::UniqueModern, sizeof(gamertag), gamertag, NULL);
+
+    if (SUCCEEDED(hr)) {
+        SDL_Log("User logged in: %s", gamertag);
+    } else {
+        SDL_Log("[GDK] UserLoggedIn -- XUserGetGamertag failed: 0x%08x.", hr);
+    }
+
+    XUserCloseHandle(user);
+}
+
+void
+AddUserUICallback(XAsyncBlock *asyncBlock)
+{
+    HRESULT hr;
+    XUserHandle user = NULL;
+
+    hr = XUserAddResult(asyncBlock, &user);
+    if (SUCCEEDED(hr)) {
+        uint64_t userId;
+
+        hr = XUserGetId(user, &userId);
+        if (FAILED(hr)) {
+            /* If unable to get the user ID, it means the account is banned, etc. */
+            SDL_Log("[GDK] AddUserSilentCallback -- XUserGetId failed: 0x%08x.", hr);
+            XUserCloseHandle(user);
+
+            /* Per the docs, likely should call XUserResolveIssueWithUiAsync here. */
+        } else {
+            UserLoggedIn(user);
+        }
+    } else {
+        SDL_Log("[GDK] AddUserUICallback -- XUserAddAsync failed: 0x%08x.", hr);
+    }
+
+    delete asyncBlock;
+}
+
+void
+AddUserUI()
+{
+    HRESULT hr;
+    XAsyncBlock *asyncBlock = new XAsyncBlock;
+
+    asyncBlock->context = NULL;
+    asyncBlock->queue = NULL; /* A null queue will use the global process task queue */
+    asyncBlock->callback = &AddUserUICallback;
+
+    hr = XUserAddAsync(XUserAddOptions::None, asyncBlock);
+
+    if (FAILED(hr)) {
+        delete asyncBlock;
+        SDL_Log("[GDK] AddUserSilent -- failed: 0x%08x", hr);
+    }
+}
+
+void
+AddUserSilentCallback(XAsyncBlock *asyncBlock)
+{
+    HRESULT hr;
+    XUserHandle user = NULL;
+
+    hr = XUserAddResult(asyncBlock, &user);
+    if (SUCCEEDED(hr)) {
+        uint64_t userId;
+
+        hr = XUserGetId(user, &userId);
+        if (FAILED(hr)) {
+            /* If unable to get the user ID, it means the account is banned, etc. */
+            SDL_Log("[GDK] AddUserSilentCallback -- XUserGetId failed: 0x%08x. Trying with UI.", hr);
+            XUserCloseHandle(user);
+            AddUserUI();
+        } else {
+            UserLoggedIn(user);
+        }
+    } else {
+        SDL_Log("[GDK] AddUserSilentCallback -- XUserAddAsync failed: 0x%08x. Trying with UI.", hr);
+        AddUserUI();
+    }
+
+    delete asyncBlock;
+}
+
+void
+AddUserSilent()
+{
+    HRESULT hr;
+    XAsyncBlock *asyncBlock = new XAsyncBlock;
+
+    asyncBlock->context = NULL;
+    asyncBlock->queue = NULL; /* A null queue will use the global process task queue */
+    asyncBlock->callback = &AddUserSilentCallback;
+
+    hr = XUserAddAsync(XUserAddOptions::AddDefaultUserSilently, asyncBlock);
+
+    if (FAILED(hr)) {
+        delete asyncBlock;
+        SDL_Log("[GDK] AddUserSilent -- failed: 0x%08x", hr);
+    }
+}
+
+int
+LoadSprite(const char *file)
+{
+    int i;
+
+    for (i = 0; i < state->num_windows; ++i) {
+        /* This does the SDL_LoadBMP step repeatedly, but that's OK for test code. */
+        sprites[i] = LoadTexture(state->renderers[i], file, SDL_TRUE, &sprite_w, &sprite_h);
+        if (!sprites[i]) {
+            return -1;
+        }
+        if (SDL_SetTextureBlendMode(sprites[i], blendMode) < 0) {
+            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set blend mode: %s\n", SDL_GetError());
+            SDL_DestroyTexture(sprites[i]);
+            return -1;
+        }
+    }
+
+    /* We're ready to roll. :) */
+    return 0;
+}
+
+void
+DrawSprites(SDL_Renderer * renderer, SDL_Texture * sprite)
+{
+    SDL_Rect viewport, temp;
+
+    /* Query the sizes */
+    SDL_RenderGetViewport(renderer, &viewport);
+
+    /* Cycle the color and alpha, if desired */
+    if (cycle_color) {
+        current_color += cycle_direction;
+        if (current_color < 0) {
+            current_color = 0;
+            cycle_direction = -cycle_direction;
+        }
+        if (current_color > 255) {
+            current_color = 255;
+            cycle_direction = -cycle_direction;
+        }
+        SDL_SetTextureColorMod(sprite, 255, (Uint8) current_color,
+                               (Uint8) current_color);
+    }
+    if (cycle_alpha) {
+        current_alpha += cycle_direction;
+        if (current_alpha < 0) {
+            current_alpha = 0;
+            cycle_direction = -cycle_direction;
+        }
+        if (current_alpha > 255) {
+            current_alpha = 255;
+            cycle_direction = -cycle_direction;
+        }
+        SDL_SetTextureAlphaMod(sprite, (Uint8) current_alpha);
+    }
+
+    /* Draw a gray background */
+    SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
+    SDL_RenderClear(renderer);
+
+    /* Test points */
+    SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0x00, 0xFF);
+    SDL_RenderDrawPoint(renderer, 0, 0);
+    SDL_RenderDrawPoint(renderer, viewport.w-1, 0);
+    SDL_RenderDrawPoint(renderer, 0, viewport.h-1);
+    SDL_RenderDrawPoint(renderer, viewport.w-1, viewport.h-1);
+
+    /* Test horizontal and vertical lines */
+    SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0xFF);
+    SDL_RenderDrawLine(renderer, 1, 0, viewport.w-2, 0);
+    SDL_RenderDrawLine(renderer, 1, viewport.h-1, viewport.w-2, viewport.h-1);
+    SDL_RenderDrawLine(renderer, 0, 1, 0, viewport.h-2);
+    SDL_RenderDrawLine(renderer, viewport.w-1, 1, viewport.w-1, viewport.h-2);
+
+    /* Test fill and copy */
+    SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
+    temp.x = 1;
+    temp.y = 1;
+    temp.w = sprite_w;
+    temp.h = sprite_h;
+    SDL_RenderFillRect(renderer, &temp);
+    SDL_RenderCopy(renderer, sprite, NULL, &temp);
+    temp.x = viewport.w-sprite_w-1;
+    temp.y = 1;
+    temp.w = sprite_w;
+    temp.h = sprite_h;
+    SDL_RenderFillRect(renderer, &temp);
+    SDL_RenderCopy(renderer, sprite, NULL, &temp);
+    temp.x = 1;
+    temp.y = viewport.h-sprite_h-1;
+    temp.w = sprite_w;
+    temp.h = sprite_h;
+    SDL_RenderFillRect(renderer, &temp);
+    SDL_RenderCopy(renderer, sprite, NULL, &temp);
+    temp.x = viewport.w-sprite_w-1;
+    temp.y = viewport.h-sprite_h-1;
+    temp.w = sprite_w;
+    temp.h = sprite_h;
+    SDL_RenderFillRect(renderer, &temp);
+    SDL_RenderCopy(renderer, sprite, NULL, &temp);
+
+    /* Test diagonal lines */
+    SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0xFF);
+    SDL_RenderDrawLine(renderer, sprite_w, sprite_h,
+                       viewport.w-sprite_w-2, viewport.h-sprite_h-2);
+    SDL_RenderDrawLine(renderer, viewport.w-sprite_w-2, sprite_h,
+                       sprite_w, viewport.h-sprite_h-2);
+
+    /* Update the screen! */
+    SDL_RenderPresent(renderer);
+}
+
+void
+loop()
+{
+    int i;
+    SDL_Event event;
+
+    /* Check for events */
+    while (SDL_PollEvent(&event)) {
+        if (event.type == SDL_KEYDOWN && !event.key.repeat) {
+            SDL_Log("Initial SDL_KEYDOWN: %s", SDL_GetScancodeName(event.key.keysym.scancode));
+        }
+#if defined(__XBOXONE__) || defined(__XBOXSERIES__)
+        /* On Xbox, ignore the keydown event because the features aren't supported */
+        if (event.type != SDL_KEYDOWN) {
+            SDLTest_CommonEvent(state, &event, &done);
+        }
+#else
+        SDLTest_CommonEvent(state, &event, &done);
+#endif
+    }
+    for (i = 0; i < state->num_windows; ++i) {
+        if (state->windows[i] == NULL) {
+            continue;
+        }
+        DrawSprites(state->renderers[i], sprites[i]);
+    }
+}
+
+int
+main(int argc, char *argv[])
+{
+    int i;
+    const char *icon = "icon.bmp";
+    char *soundname = NULL;
+
+    /* Initialize parameters */
+    num_sprites = NUM_SPRITES;
+
+    /* Initialize test framework */
+    state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO | SDL_INIT_AUDIO);
+    if (!state) {
+        return 1;
+    }
+
+    for (i = 1; i < argc;) {
+        int consumed;
+
+        consumed = SDLTest_CommonArg(state, i);
+        if (consumed == 0) {
+            consumed = -1;
+            if (SDL_strcasecmp(argv[i], "--blend") == 0) {
+                if (argv[i + 1]) {
+                    if (SDL_strcasecmp(argv[i + 1], "none") == 0) {
+                        blendMode = SDL_BLENDMODE_NONE;
+                        consumed = 2;
+                    } else if (SDL_strcasecmp(argv[i + 1], "blend") == 0) {
+                        blendMode = SDL_BLENDMODE_BLEND;
+                        consumed = 2;
+                    } else if (SDL_strcasecmp(argv[i + 1], "add") == 0) {
+                        blendMode = SDL_BLENDMODE_ADD;
+                        consumed = 2;
+                    } else if (SDL_strcasecmp(argv[i + 1], "mod") == 0) {
+                        blendMode = SDL_BLENDMODE_MOD;
+                        consumed = 2;
+                    } else if (SDL_strcasecmp(argv[i + 1], "sub") == 0) {
+                        blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_SUBTRACT, SDL_BLENDFACTOR_ZERO, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_SUBTRACT);
+                        consumed = 2;
+                    }
+                }
+            } else if (SDL_strcasecmp(argv[i], "--cyclecolor") == 0) {
+                cycle_color = SDL_TRUE;
+                consumed = 1;
+            } else if (SDL_strcasecmp(argv[i], "--cyclealpha") == 0) {
+                cycle_alpha = SDL_TRUE;
+                consumed = 1;
+            } else if (SDL_isdigit(*argv[i])) {
+                num_sprites = SDL_atoi(argv[i]);
+                consumed = 1;
+            } else if (argv[i][0] != '-') {
+                icon = argv[i];
+                consumed = 1;
+            }
+        }
+        if (consumed < 0) {
+            static const char *options[] = {
+                "[--blend none|blend|add|mod]",
+                "[--cyclecolor]",
+                "[--cyclealpha]",
+                "[num_sprites]",
+                "[icon.bmp]",
+                NULL };
+            SDLTest_CommonLogUsage(state, argv[0], options);
+            quit(1);
+        }
+        i += consumed;
+    }
+    if (!SDLTest_CommonInit(state)) {
+        quit(2);
+    }
+
+    /* Create the windows, initialize the renderers, and load the textures */
+    sprites =
+        (SDL_Texture **) SDL_malloc(state->num_windows * sizeof(*sprites));
+    if (!sprites) {
+        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!\n");
+        quit(2);
+    }
+    for (i = 0; i < state->num_windows; ++i) {
+        SDL_Renderer *renderer = state->renderers[i];
+        SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
+        SDL_RenderClear(renderer);
+    }
+    if (LoadSprite(icon) < 0) {
+        quit(2);
+    }
+
+    soundname = GetResourceFilename(argc > 1 ? argv[1] : NULL, "sample.wav");
+
+    if (!soundname) {
+        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s\n", SDL_GetError());
+        quit(1);
+    }
+
+    /* Load the wave file into memory */
+    if (SDL_LoadWAV(soundname, &wave.spec, &wave.sound, &wave.soundlen) == NULL) {
+        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", soundname, SDL_GetError());
+        quit(1);
+    }
+
+    wave.spec.callback = fillerup;
+
+    /* Show the list of available drivers */
+    SDL_Log("Available audio drivers:");
+    for (i = 0; i < SDL_GetNumAudioDrivers(); ++i) {
+        SDL_Log("%i: %s", i, SDL_GetAudioDriver(i));
+    }
+
+    SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver());
+
+    open_audio();
+
+    /* Main render loop */
+    done = 0;
+
+    /* Try to add the default user silently */
+    AddUserSilent();
+
+    while (!done) {
+        loop();
+    }
+
+    quit(0);
+
+    SDL_free(soundname);
+    return 0;
+}
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 34 - 0
Engine/lib/sdl/VisualC-GDK/tests/testgdk/wingdk/MicrosoftGame.config

@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Game configVersion="1">
+
+	<!-- Set these to the correct identifiers from Partner Center -->
+	<Identity Name="SDL"
+		Version="1.0.0.0"
+		Publisher="CN=Publisher"/>
+
+	<ExecutableList>
+		<Executable Name="testgdk.exe"
+					TargetDeviceFamily="PC"
+					Id="Game" />
+	</ExecutableList>
+
+	<DesktopRegistration>
+		<DependencyList>
+			<KnownDependency Name="VC14"/>
+		</DependencyList>
+	</DesktopRegistration>
+
+	<!-- Set these to the correct values from Partner Center -->
+	<MSAAppId>PleaseChangeMe</MSAAppId>
+	<TitleId>FFFFFFFF</TitleId>
+
+	<ShellVisuals DefaultDisplayName="testgdk"
+					PublisherDisplayName="SDL"
+					Square480x480Logo="Logo480x480.png"
+					Square150x150Logo="Logo150x150.png"
+					Square44x44Logo="Logo44x44.png"
+					Description="testgdk"
+					ForegroundText="light"
+					BackgroundColor="#000000"
+					StoreLogo="Logo100x100.png"/>
+</Game>

+ 29 - 0
Engine/lib/sdl/VisualC-GDK/tests/testgdk/xboxone/MicrosoftGame.config

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Game configVersion="1">
+
+	<!-- Set these to the correct identifiers from Partner Center -->
+	<Identity Name="SDL"
+		Version="1.0.0.0"
+		Publisher="CN=Publisher"/>
+
+	<ExecutableList>
+		<Executable Name="testgdk.exe"
+					TargetDeviceFamily="XboxOne"
+					Id="Game" />
+	</ExecutableList>
+
+	<!-- Set these to the correct values from Partner Center -->
+	<MSAAppId>PleaseChangeMe</MSAAppId>
+	<TitleId>FFFFFFFF</TitleId>
+
+	<ShellVisuals DefaultDisplayName="testgdk"
+					PublisherDisplayName="SDL"
+					Square480x480Logo="Logo480x480.png"
+					Square150x150Logo="Logo150x150.png"
+					Square44x44Logo="Logo44x44.png"
+					SplashScreenImage="SplashScreenImage.png"
+					Description="testgdk"
+					ForegroundText="light"
+					BackgroundColor="#000000"
+					StoreLogo="Logo100x100.png"/>
+</Game>

+ 29 - 0
Engine/lib/sdl/VisualC-GDK/tests/testgdk/xboxseries/MicrosoftGame.config

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Game configVersion="1">
+
+	<!-- Set these to the correct identifiers from Partner Center -->
+	<Identity Name="SDL"
+		Version="1.0.0.0"
+		Publisher="CN=Publisher"/>
+
+	<ExecutableList>
+		<Executable Name="testgdk.exe"
+					TargetDeviceFamily="Scarlett"
+					Id="Game" />
+	</ExecutableList>
+
+	<!-- Set these to the correct values from Partner Center -->
+	<MSAAppId>PleaseChangeMe</MSAAppId>
+	<TitleId>FFFFFFFF</TitleId>
+
+	<ShellVisuals DefaultDisplayName="testgdk"
+					PublisherDisplayName="SDL"
+					Square480x480Logo="Logo480x480.png"
+					Square150x150Logo="Logo150x150.png"
+					Square44x44Logo="Logo44x44.png"
+					SplashScreenImage="SplashScreenImage.png"
+					Description="testgdk"
+					ForegroundText="light"
+					BackgroundColor="#000000"
+					StoreLogo="Logo100x100.png"/>
+</Game>

+ 9 - 0
Engine/lib/sdl/VisualC-GDK/tests/testsprite2/PackageLayout.xml

@@ -0,0 +1,9 @@
+<Package>
+  <Chunk Id="1000" Marker="Launch">
+    <FileGroup DestinationPath="." SourcePath="." Include="testsprite2.exe" />
+    <FileGroup DestinationPath="." SourcePath="." Include="MicrosoftGame.config" />
+    <FileGroup DestinationPath="." SourcePath="." Include="*.bmp" />
+    <FileGroup DestinationPath="." SourcePath="." Include="*.png" />
+    <FileGroup DestinationPath="." SourcePath="." Include="*.dll" />
+  </Chunk>
+</Package>

+ 34 - 0
Engine/lib/sdl/VisualC-GDK/tests/testsprite2/wingdk/MicrosoftGame.config

@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Game configVersion="1">
+
+	<!-- Set these to the correct identifiers from Partner Center -->
+	<Identity Name="SDL"
+		Version="1.0.0.0"
+		Publisher="CN=Publisher"/>
+
+	<ExecutableList>
+		<Executable Name="testsprite2.exe"
+					TargetDeviceFamily="PC"
+					Id="Game" />
+	</ExecutableList>
+
+	<DesktopRegistration>
+		<DependencyList>
+			<KnownDependency Name="VC14"/>
+		</DependencyList>
+	</DesktopRegistration>
+
+	<!-- Set these to the correct values from Partner Center -->
+	<MSAAppId>PleaseChangeMe</MSAAppId>
+	<TitleId>FFFFFFFF</TitleId>
+
+	<ShellVisuals DefaultDisplayName="testsprite2"
+					PublisherDisplayName="SDL"
+					Square480x480Logo="Logo480x480.png"
+					Square150x150Logo="Logo150x150.png"
+					Square44x44Logo="Logo44x44.png"
+					Description="testsprite2"
+					ForegroundText="light"
+					BackgroundColor="#000000"
+					StoreLogo="Logo100x100.png"/>
+</Game>

+ 29 - 0
Engine/lib/sdl/VisualC-GDK/tests/testsprite2/xboxone/MicrosoftGame.config

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Game configVersion="1">
+
+	<!-- Set these to the correct identifiers from Partner Center -->
+	<Identity Name="SDL"
+		Version="1.0.0.0"
+		Publisher="CN=Publisher"/>
+
+	<ExecutableList>
+		<Executable Name="testsprite2.exe"
+					TargetDeviceFamily="XboxOne"
+					Id="Game" />
+	</ExecutableList>
+
+	<!-- Set these to the correct values from Partner Center -->
+	<MSAAppId>PleaseChangeMe</MSAAppId>
+	<TitleId>FFFFFFFF</TitleId>
+
+	<ShellVisuals DefaultDisplayName="testsprite2"
+					PublisherDisplayName="SDL"
+					Square480x480Logo="Logo480x480.png"
+					Square150x150Logo="Logo150x150.png"
+					Square44x44Logo="Logo44x44.png"
+					SplashScreenImage="SplashScreenImage.png"
+					Description="testsprite2"
+					ForegroundText="light"
+					BackgroundColor="#000000"
+					StoreLogo="Logo100x100.png"/>
+</Game>

+ 29 - 0
Engine/lib/sdl/VisualC-GDK/tests/testsprite2/xboxseries/MicrosoftGame.config

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Game configVersion="1">
+
+	<!-- Set these to the correct identifiers from Partner Center -->
+	<Identity Name="SDL"
+		Version="1.0.0.0"
+		Publisher="CN=Publisher"/>
+
+	<ExecutableList>
+		<Executable Name="testsprite2.exe"
+					TargetDeviceFamily="Scarlett"
+					Id="Game" />
+	</ExecutableList>
+
+	<!-- Set these to the correct values from Partner Center -->
+	<MSAAppId>PleaseChangeMe</MSAAppId>
+	<TitleId>FFFFFFFF</TitleId>
+
+	<ShellVisuals DefaultDisplayName="testsprite2"
+					PublisherDisplayName="SDL"
+					Square480x480Logo="Logo480x480.png"
+					Square150x150Logo="Logo150x150.png"
+					Square44x44Logo="Logo44x44.png"
+					Description="testsprite2"
+					SplashScreenImage="SplashScreenImage.png"
+					ForegroundText="light"
+					BackgroundColor="#000000"
+					StoreLogo="Logo100x100.png"/>
+</Game>

+ 5 - 3
Engine/lib/sdl/VisualC/pkg-support/cmake/sdl2-config.cmake

@@ -1,7 +1,7 @@
 # SDL2 CMake configuration file:
 # SDL2 CMake configuration file:
 # This file is meant to be placed in a cmake subfolder of SDL2-devel-2.x.y-VC
 # This file is meant to be placed in a cmake subfolder of SDL2-devel-2.x.y-VC
 
 
-cmake_minimum_required(VERSION 3.0...3.5)
+cmake_minimum_required(VERSION 3.0...3.28)
 
 
 include(FeatureSummary)
 include(FeatureSummary)
 set_package_properties(SDL2 PROPERTIES
 set_package_properties(SDL2 PROPERTIES
@@ -79,6 +79,8 @@ endif()
 unset(_sdl2_library)
 unset(_sdl2_library)
 unset(_sdl2_dll_library)
 unset(_sdl2_dll_library)
 
 
+set(SDL2_SDL2-static_FOUND FALSE)
+
 set(_sdl2main_library "${SDL2_LIBDIR}/SDL2main.lib")
 set(_sdl2main_library "${SDL2_LIBDIR}/SDL2main.lib")
 if(EXISTS "${_sdl2main_library}")
 if(EXISTS "${_sdl2main_library}")
     if(NOT TARGET SDL2::SDL2main)
     if(NOT TARGET SDL2::SDL2main)
@@ -92,7 +94,7 @@ if(EXISTS "${_sdl2main_library}")
     endif()
     endif()
     set(SDL2_SDL2main_FOUND TRUE)
     set(SDL2_SDL2main_FOUND TRUE)
 else()
 else()
-    set(SDL2_SDL2_FOUND FALSE)
+    set(SDL2_SDL2main_FOUND FALSE)
 endif()
 endif()
 unset(_sdl2main_library)
 unset(_sdl2main_library)
 
 
@@ -110,7 +112,7 @@ if(EXISTS "${_sdl2test_library}")
     endif()
     endif()
     set(SDL2_SDL2test_FOUND TRUE)
     set(SDL2_SDL2test_FOUND TRUE)
 else()
 else()
-    set(SDL2_SDL2_FOUND FALSE)
+    set(SDL2_SDL2test_FOUND FALSE)
 endif()
 endif()
 unset(_sdl2test_library)
 unset(_sdl2test_library)
 
 

+ 19 - 0
Engine/lib/sdl/WhatsNew.txt

@@ -1,9 +1,28 @@
 
 
 This is a list of major changes in SDL's version history.
 This is a list of major changes in SDL's version history.
 
 
+---------------------------------------------------------------------------
+2.30.0:
+---------------------------------------------------------------------------
+
+General:
+* Added support for 2 bits-per-pixel indexed surface formats
+* Added the function SDL_GameControllerGetSteamHandle() to get the Steam API handle for a controller, if available
+* Added the event SDL_CONTROLLERSTEAMHANDLEUPDATED which is sent when the Steam API handle for a controller changes. This could also change the name, VID, and PID of the controller.
+* Added the environment variable SDL_LOGGING to control default log output
+
+macOS:
+* Added the hint SDL_HINT_JOYSTICK_IOKIT to control whether the IOKit controller driver should be used
+* Added the hint SDL_HINT_JOYSTICK_MFI to control whether the GCController controller driver should be used
+* Added the hint SDL_HINT_RENDER_METAL_PREFER_LOW_POWER_DEVICE to choose whether high or low power GPU should be used for rendering, in the case where there are multiple GPUs available
+
+Xbox:
+* Added the function SDL_GDKGetDefaultUser()
+
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 2.28.2:
 2.28.2:
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
+
 General:
 General:
 * Added the hint SDL_HINT_JOYSTICK_WGI to control whether to use Windows.Gaming.Input for controllers
 * Added the hint SDL_HINT_JOYSTICK_WGI to control whether to use Windows.Gaming.Input for controllers
 
 

+ 5 - 5
Engine/lib/sdl/Xcode-iOS/Demos/src/accelerometer.c

@@ -118,7 +118,7 @@ initializeTextures(SDL_Renderer *renderer)
 
 
     /* load the ship */
     /* load the ship */
     bmp_surface = SDL_LoadBMP("ship.bmp");
     bmp_surface = SDL_LoadBMP("ship.bmp");
-    if (bmp_surface == NULL) {
+    if (!bmp_surface) {
         fatalError("could not ship.bmp");
         fatalError("could not ship.bmp");
     }
     }
     /* set blue to transparent on the ship */
     /* set blue to transparent on the ship */
@@ -127,7 +127,7 @@ initializeTextures(SDL_Renderer *renderer)
 
 
     /* create ship texture from surface */
     /* create ship texture from surface */
     ship = SDL_CreateTextureFromSurface(renderer, bmp_surface);
     ship = SDL_CreateTextureFromSurface(renderer, bmp_surface);
-    if (ship == NULL) {
+    if (!ship) {
         fatalError("could not create ship texture");
         fatalError("could not create ship texture");
     }
     }
     SDL_SetTextureBlendMode(ship, SDL_BLENDMODE_BLEND);
     SDL_SetTextureBlendMode(ship, SDL_BLENDMODE_BLEND);
@@ -140,12 +140,12 @@ initializeTextures(SDL_Renderer *renderer)
 
 
     /* load the space background */
     /* load the space background */
     bmp_surface = SDL_LoadBMP("space.bmp");
     bmp_surface = SDL_LoadBMP("space.bmp");
-    if (bmp_surface == NULL) {
+    if (!bmp_surface) {
         fatalError("could not load space.bmp");
         fatalError("could not load space.bmp");
     }
     }
     /* create space texture from surface */
     /* create space texture from surface */
     space = SDL_CreateTextureFromSurface(renderer, bmp_surface);
     space = SDL_CreateTextureFromSurface(renderer, bmp_surface);
-    if (space == NULL) {
+    if (!space) {
         fatalError("could not create space texture");
         fatalError("could not create space texture");
     }
     }
     SDL_FreeSurface(bmp_surface);
     SDL_FreeSurface(bmp_surface);
@@ -179,7 +179,7 @@ main(int argc, char *argv[])
     printf("There are %d joysticks available\n", SDL_NumJoysticks());
     printf("There are %d joysticks available\n", SDL_NumJoysticks());
     printf("Default joystick (index 0) is %s\n", SDL_JoystickName(0));
     printf("Default joystick (index 0) is %s\n", SDL_JoystickName(0));
     accelerometer = SDL_JoystickOpen(0);
     accelerometer = SDL_JoystickOpen(0);
-    if (accelerometer == NULL) {
+    if (!accelerometer) {
         fatalError("Could not open joystick (accelerometer)");
         fatalError("Could not open joystick (accelerometer)");
     }
     }
     printf("joystick number of axis = %d\n",
     printf("joystick number of axis = %d\n",

+ 5 - 5
Engine/lib/sdl/Xcode-iOS/Demos/src/fireworks.c

@@ -52,9 +52,9 @@ void spawnTrailFromEmitter(struct particle *emitter);
 void spawnEmitterParticle(GLfloat x, GLfloat y);
 void spawnEmitterParticle(GLfloat x, GLfloat y);
 void explodeEmitter(struct particle *emitter);
 void explodeEmitter(struct particle *emitter);
 void initializeParticles(void);
 void initializeParticles(void);
-void initializeTexture();
+void initializeTexture(void);
 int nextPowerOfTwo(int x);
 int nextPowerOfTwo(int x);
-void drawParticles();
+void drawParticles(void);
 void stepParticles(double deltaTime);
 void stepParticles(double deltaTime);
 
 
 /*  helper function (used in texture loading)
 /*  helper function (used in texture loading)
@@ -159,7 +159,7 @@ stepParticles(double deltaTime)
     This draws all the particles shown on screen
     This draws all the particles shown on screen
 */
 */
 void
 void
-drawParticles()
+drawParticles(void)
 {
 {
 
 
     /* draw the background */
     /* draw the background */
@@ -324,7 +324,7 @@ initializeParticles(void)
     loads the particle texture
     loads the particle texture
  */
  */
 void
 void
-initializeTexture()
+initializeTexture(void)
 {
 {
 
 
     int bpp;                    /* texture bits per pixel */
     int bpp;                    /* texture bits per pixel */
@@ -334,7 +334,7 @@ initializeTexture()
                                            to format passed into OpenGL */
                                            to format passed into OpenGL */
 
 
     bmp_surface = SDL_LoadBMP("stroke.bmp");
     bmp_surface = SDL_LoadBMP("stroke.bmp");
-    if (bmp_surface == NULL) {
+    if (!bmp_surface) {
         fatalError("could not load stroke.bmp");
         fatalError("could not load stroke.bmp");
     }
     }
 
 

+ 2 - 2
Engine/lib/sdl/Xcode-iOS/Demos/src/happy.c

@@ -108,7 +108,7 @@ initializeTexture(SDL_Renderer *renderer)
     SDL_Surface *bmp_surface;
     SDL_Surface *bmp_surface;
     /* load the bmp */
     /* load the bmp */
     bmp_surface = SDL_LoadBMP("icon.bmp");
     bmp_surface = SDL_LoadBMP("icon.bmp");
-    if (bmp_surface == NULL) {
+    if (!bmp_surface) {
         fatalError("could not load bmp");
         fatalError("could not load bmp");
     }
     }
     /* set white to transparent on the happyface */
     /* set white to transparent on the happyface */
@@ -117,7 +117,7 @@ initializeTexture(SDL_Renderer *renderer)
 
 
     /* convert RGBA surface to texture */
     /* convert RGBA surface to texture */
     texture = SDL_CreateTextureFromSurface(renderer, bmp_surface);
     texture = SDL_CreateTextureFromSurface(renderer, bmp_surface);
-    if (texture == NULL) {
+    if (!texture) {
         fatalError("could not create texture");
         fatalError("could not create texture");
     }
     }
     SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
     SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);

+ 3 - 3
Engine/lib/sdl/Xcode-iOS/Demos/src/keyboard.c

@@ -165,7 +165,7 @@ loadFont(void)
 {
 {
     SDL_Surface *surface = SDL_LoadBMP("kromasky_16x16.bmp");
     SDL_Surface *surface = SDL_LoadBMP("kromasky_16x16.bmp");
 
 
-    if (surface == NULL) {
+    if (!surface) {
         printf("Error loading bitmap: %s\n", SDL_GetError());
         printf("Error loading bitmap: %s\n", SDL_GetError());
         return 0;
         return 0;
     } else {
     } else {
@@ -183,7 +183,7 @@ loadFont(void)
         SDL_BlitSurface(surface, NULL, converted, NULL);
         SDL_BlitSurface(surface, NULL, converted, NULL);
         /* create our texture */
         /* create our texture */
         texture = SDL_CreateTextureFromSurface(renderer, converted);
         texture = SDL_CreateTextureFromSurface(renderer, converted);
-        if (texture == NULL) {
+        if (!texture) {
             printf("texture creation failed: %s\n", SDL_GetError());
             printf("texture creation failed: %s\n", SDL_GetError());
         } else {
         } else {
             /* set blend mode for our texture */
             /* set blend mode for our texture */
@@ -196,7 +196,7 @@ loadFont(void)
 }
 }
 
 
 void
 void
-draw()
+draw(void)
 {
 {
     SDL_SetRenderDrawColor(renderer, bg_color.r, bg_color.g, bg_color.b, bg_color.a);
     SDL_SetRenderDrawColor(renderer, bg_color.r, bg_color.g, bg_color.b, bg_color.a);
     SDL_RenderClear(renderer);
     SDL_RenderClear(renderer);

+ 2 - 2
Engine/lib/sdl/Xcode-iOS/Demos/src/rectangles.c

@@ -58,11 +58,11 @@ main(int argc, char *argv[])
 
 
     /* create window and renderer */
     /* create window and renderer */
     window = SDL_CreateWindow(NULL, 0, 0, 320, 480, SDL_WINDOW_ALLOW_HIGHDPI);
     window = SDL_CreateWindow(NULL, 0, 0, 320, 480, SDL_WINDOW_ALLOW_HIGHDPI);
-    if (window == NULL) {
+    if (!window) {
         fatalError("Could not initialize Window");
         fatalError("Could not initialize Window");
     }
     }
     renderer = SDL_CreateRenderer(window, -1, 0);
     renderer = SDL_CreateRenderer(window, -1, 0);
-    if (renderer == NULL) {
+    if (!renderer) {
         fatalError("Could not create renderer");
         fatalError("Could not create renderer");
     }
     }
 
 

+ 2 - 2
Engine/lib/sdl/Xcode-iOS/Demos/src/touch.c

@@ -57,13 +57,13 @@ initializeTexture(SDL_Renderer *renderer)
 {
 {
     SDL_Surface *bmp_surface;
     SDL_Surface *bmp_surface;
     bmp_surface = SDL_LoadBMP("stroke.bmp");
     bmp_surface = SDL_LoadBMP("stroke.bmp");
-    if (bmp_surface == NULL) {
+    if (!bmp_surface) {
         fatalError("could not load stroke.bmp");
         fatalError("could not load stroke.bmp");
     }
     }
     brush =
     brush =
         SDL_CreateTextureFromSurface(renderer, bmp_surface);
         SDL_CreateTextureFromSurface(renderer, bmp_surface);
     SDL_FreeSurface(bmp_surface);
     SDL_FreeSurface(bmp_surface);
-    if (brush == NULL) {
+    if (!brush) {
         fatalError("could not create brush texture");
         fatalError("could not create brush texture");
     }
     }
     /* additive blending -- laying strokes on top of eachother makes them brighter */
     /* additive blending -- laying strokes on top of eachother makes them brighter */

+ 2 - 2
Engine/lib/sdl/Xcode/SDL/Info-Framework.plist

@@ -19,10 +19,10 @@
 	<key>CFBundlePackageType</key>
 	<key>CFBundlePackageType</key>
 	<string>FMWK</string>
 	<string>FMWK</string>
 	<key>CFBundleShortVersionString</key>
 	<key>CFBundleShortVersionString</key>
-	<string>2.28.4</string>
+	<string>2.32.6</string>
 	<key>CFBundleSignature</key>
 	<key>CFBundleSignature</key>
 	<string>SDLX</string>
 	<string>SDLX</string>
 	<key>CFBundleVersion</key>
 	<key>CFBundleVersion</key>
-	<string>2.28.4</string>
+	<string>2.32.6</string>
 </dict>
 </dict>
 </plist>
 </plist>

File diff suppressed because it is too large
+ 220 - 68
Engine/lib/sdl/Xcode/SDL/SDL.xcodeproj/project.pbxproj


+ 1 - 1
Engine/lib/sdl/Xcode/SDL/pkg-support/SDL.info

@@ -1,4 +1,4 @@
-Title SDL 2.28.4
+Title SDL 2.32.6
 Version 1
 Version 1
 Description SDL Library for Mac OS X (http://www.libsdl.org)
 Description SDL Library for Mac OS X (http://www.libsdl.org)
 DefaultLocation /Library/Frameworks
 DefaultLocation /Library/Frameworks

+ 12 - 5
Engine/lib/sdl/Xcode/SDL/pkg-support/resources/CMake/sdl2-config.cmake

@@ -31,8 +31,15 @@ endmacro()
 
 
 set(SDL2_FOUND TRUE)
 set(SDL2_FOUND TRUE)
 
 
-string(REGEX REPLACE "SDL2\\.framework.*" "SDL2.framework" SDL2_FRAMEWORK_PATH "${CMAKE_CURRENT_LIST_DIR}")
-string(REGEX REPLACE "SDL2\\.framework.*" "" SDL2_FRAMEWORK_PARENT_PATH "${CMAKE_CURRENT_LIST_DIR}")
+# Compute the installation prefix relative to this file.
+set(SDL2_FRAMEWORK_PATH "${CMAKE_CURRENT_LIST_DIR}")                                # > /SDL2.framework/Resources/CMake/
+get_filename_component(SDL2_FRAMEWORK_PATH "${SDL2_FRAMEWORK_PATH}" REALPATH)       # > /SDL2.framework/Versions/Current/Resources/CMake
+get_filename_component(SDL2_FRAMEWORK_PATH "${SDL2_FRAMEWORK_PATH}" REALPATH)       # > /SDL2.framework/Versions/A/Resources/CMake/
+get_filename_component(SDL2_FRAMEWORK_PATH "${SDL2_FRAMEWORK_PATH}" PATH)           # > /SDL2.framework/Versions/A/Resources/
+get_filename_component(SDL2_FRAMEWORK_PATH "${SDL2_FRAMEWORK_PATH}" PATH)           # > /SDL2.framework/Versions/A/
+get_filename_component(SDL2_FRAMEWORK_PATH "${SDL2_FRAMEWORK_PATH}" PATH)           # > /SDL2.framework/Versions/
+get_filename_component(SDL2_FRAMEWORK_PATH "${SDL2_FRAMEWORK_PATH}" PATH)           # > /SDL2.framework/
+get_filename_component(SDL2_FRAMEWORK_PARENT_PATH "${SDL2_FRAMEWORK_PATH}" PATH)    # > /
 
 
 # For compatibility with autotools sdl2-config.cmake, provide SDL2_* variables.
 # For compatibility with autotools sdl2-config.cmake, provide SDL2_* variables.
 
 
@@ -49,12 +56,12 @@ set(SDL2_LIBRARIES "SDL2::SDL2")
 # This is done for compatibility with CMake generated SDL2-target.cmake files.
 # This is done for compatibility with CMake generated SDL2-target.cmake files.
 
 
 if(NOT TARGET SDL2::SDL2)
 if(NOT TARGET SDL2::SDL2)
-    add_library(SDL2::SDL2 INTERFACE IMPORTED)
+    add_library(SDL2::SDL2 SHARED IMPORTED)
     set_target_properties(SDL2::SDL2
     set_target_properties(SDL2::SDL2
         PROPERTIES
         PROPERTIES
-            INTERFACE_COMPILE_OPTIONS "SHELL:-F \"${SDL2_FRAMEWORK_PARENT_PATH}\""
+            FRAMEWORK "TRUE"
+            IMPORTED_LOCATION "${SDL2_FRAMEWORK_PATH}/Versions/A/SDL2"
             INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIRS}"
             INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIRS}"
-            INTERFACE_LINK_OPTIONS "SHELL:-F \"${SDL2_FRAMEWORK_PARENT_PATH}\";SHELL:-framework SDL2"
             COMPATIBLE_INTERFACE_BOOL "SDL2_SHARED"
             COMPATIBLE_INTERFACE_BOOL "SDL2_SHARED"
             INTERFACE_SDL2_SHARED "ON"
             INTERFACE_SDL2_SHARED "ON"
             COMPATIBLE_INTERFACE_STRING "SDL_VERSION"
             COMPATIBLE_INTERFACE_STRING "SDL_VERSION"

+ 1 - 1
Engine/lib/sdl/Xcode/SDL/pkg-support/resources/License.txt

@@ -1,6 +1,6 @@
 
 
 Simple DirectMedia Layer
 Simple DirectMedia Layer
-Copyright (C) 1997-2023 Sam Lantinga <[email protected]>
+Copyright (C) 1997-2025 Sam Lantinga <[email protected]>
   
   
 This software is provided 'as-is', without any express or implied
 This software is provided 'as-is', without any express or implied
 warranty.  In no event will the authors be held liable for any damages
 warranty.  In no event will the authors be held liable for any damages

File diff suppressed because it is too large
+ 685 - 43
Engine/lib/sdl/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj


+ 88 - 75
Engine/lib/sdl/acinclude/libtool.m4

@@ -219,8 +219,8 @@ esac
 ofile=libtool
 ofile=libtool
 can_build_shared=yes
 can_build_shared=yes
 
 
-# All known linkers require a '.a' archive for static linking (except MSVC,
-# which needs '.lib').
+# All known linkers require a '.a' archive for static linking (except MSVC and
+# ICC, which need '.lib').
 libext=a
 libext=a
 
 
 with_gnu_ld=$lt_cv_prog_gnu_ld
 with_gnu_ld=$lt_cv_prog_gnu_ld
@@ -1023,6 +1023,21 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
 	rm -f conftest.*
 	rm -f conftest.*
       fi])
       fi])
 
 
+    # Feature test to disable chained fixups since it is not
+    # compatible with '-undefined dynamic_lookup'
+    AC_CACHE_CHECK([for -no_fixup_chains linker flag],
+      [lt_cv_support_no_fixup_chains],
+      [ save_LDFLAGS=$LDFLAGS
+        LDFLAGS="$LDFLAGS -Wl,-no_fixup_chains"
+        AC_LINK_IFELSE(
+          [AC_LANG_PROGRAM([],[])],
+          lt_cv_support_no_fixup_chains=yes,
+          lt_cv_support_no_fixup_chains=no
+        )
+        LDFLAGS=$save_LDFLAGS
+      ]
+    )
+
     AC_CACHE_CHECK([for -exported_symbols_list linker flag],
     AC_CACHE_CHECK([for -exported_symbols_list linker flag],
       [lt_cv_ld_exported_symbols_list],
       [lt_cv_ld_exported_symbols_list],
       [lt_cv_ld_exported_symbols_list=no
       [lt_cv_ld_exported_symbols_list=no
@@ -1047,7 +1062,7 @@ _LT_EOF
       echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
       echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
       $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
       $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
       cat > conftest.c << _LT_EOF
       cat > conftest.c << _LT_EOF
-int main() { return 0;}
+int main(void) { return 0;}
 _LT_EOF
 _LT_EOF
       echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
       echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
       $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
       $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
@@ -1072,7 +1087,12 @@ _LT_EOF
         10.[[012]],*|,*powerpc*-darwin[[5-8]]*)
         10.[[012]],*|,*powerpc*-darwin[[5-8]]*)
           _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
           _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
         *)
         *)
-          _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+          if test yes = "$lt_cv_support_no_fixup_chains"; then
+            _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup $wl-no_fixup_chains'
+          else
+            _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup'
+          fi
+        ;;
       esac
       esac
     ;;
     ;;
   esac
   esac
@@ -1365,7 +1385,7 @@ mips64*-*linux*)
   ;;
   ;;
 
 
 x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
 x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
-s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*|x86_64-gnu*)
   # Find out what ABI is being produced by ac_compile, and set linker
   # Find out what ABI is being produced by ac_compile, and set linker
   # options accordingly.  Note that the listed cases only cover the
   # options accordingly.  Note that the listed cases only cover the
   # situations where additional linker options are needed (such as when
   # situations where additional linker options are needed (such as when
@@ -1380,7 +1400,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
 	  x86_64-*kfreebsd*-gnu)
 	  x86_64-*kfreebsd*-gnu)
 	    LD="${LD-ld} -m elf_i386_fbsd"
 	    LD="${LD-ld} -m elf_i386_fbsd"
 	    ;;
 	    ;;
-	  x86_64-*linux*)
+	  x86_64-*linux*|x86_64-gnu*)
 	    case `/usr/bin/file conftest.o` in
 	    case `/usr/bin/file conftest.o` in
 	      *x86-64*)
 	      *x86-64*)
 		LD="${LD-ld} -m elf32_x86_64"
 		LD="${LD-ld} -m elf32_x86_64"
@@ -1409,7 +1429,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
 	  x86_64-*kfreebsd*-gnu)
 	  x86_64-*kfreebsd*-gnu)
 	    LD="${LD-ld} -m elf_x86_64_fbsd"
 	    LD="${LD-ld} -m elf_x86_64_fbsd"
 	    ;;
 	    ;;
-	  x86_64-*linux*)
+	  x86_64-*linux*|x86_64-gnu*)
 	    LD="${LD-ld} -m elf_x86_64"
 	    LD="${LD-ld} -m elf_x86_64"
 	    ;;
 	    ;;
 	  powerpcle-*linux*|powerpc64le-*linux*)
 	  powerpcle-*linux*|powerpc64le-*linux*)
@@ -1540,15 +1560,8 @@ old_postinstall_cmds='chmod 644 $oldlib'
 old_postuninstall_cmds=
 old_postuninstall_cmds=
 
 
 if test -n "$RANLIB"; then
 if test -n "$RANLIB"; then
-  case $host_os in
-  bitrig* | openbsd*)
-    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
-    ;;
-  *)
-    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
-    ;;
-  esac
   old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
   old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+  old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
 fi
 fi
 
 
 case $host_os in
 case $host_os in
@@ -1687,7 +1700,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
     lt_cv_sys_max_cmd_len=-1;
     lt_cv_sys_max_cmd_len=-1;
     ;;
     ;;
 
 
-  cygwin* | mingw* | cegcc*)
+  cygwin* | mingw* | windows* | cegcc*)
     # On Win9x/ME, this test blows up -- it succeeds, but takes
     # On Win9x/ME, this test blows up -- it succeeds, but takes
     # about 5 minutes as the teststring grows exponentially.
     # about 5 minutes as the teststring grows exponentially.
     # Worse, since 9x/ME are not pre-emptively multitasking,
     # Worse, since 9x/ME are not pre-emptively multitasking,
@@ -1869,11 +1882,11 @@ else
 /* When -fvisibility=hidden is used, assume the code has been annotated
 /* When -fvisibility=hidden is used, assume the code has been annotated
    correspondingly for the symbols needed.  */
    correspondingly for the symbols needed.  */
 #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
 #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
-int fnord () __attribute__((visibility("default")));
+int fnord (void) __attribute__((visibility("default")));
 #endif
 #endif
 
 
-int fnord () { return 42; }
-int main ()
+int fnord (void) { return 42; }
+int main (void)
 {
 {
   void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
   void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
   int status = $lt_dlunknown;
   int status = $lt_dlunknown;
@@ -1930,7 +1943,7 @@ else
     lt_cv_dlopen_self=yes
     lt_cv_dlopen_self=yes
     ;;
     ;;
 
 
-  mingw* | pw32* | cegcc*)
+  mingw* | windows* | pw32* | cegcc*)
     lt_cv_dlopen=LoadLibrary
     lt_cv_dlopen=LoadLibrary
     lt_cv_dlopen_libs=
     lt_cv_dlopen_libs=
     ;;
     ;;
@@ -2298,7 +2311,7 @@ if test yes = "$GCC"; then
     *) lt_awk_arg='/^libraries:/' ;;
     *) lt_awk_arg='/^libraries:/' ;;
   esac
   esac
   case $host_os in
   case $host_os in
-    mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;;
+    mingw* | windows* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;;
     *) lt_sed_strip_eq='s|=/|/|g' ;;
     *) lt_sed_strip_eq='s|=/|/|g' ;;
   esac
   esac
   lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
   lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
@@ -2356,7 +2369,7 @@ BEGIN {RS = " "; FS = "/|\n";} {
   # AWK program above erroneously prepends '/' to C:/dos/paths
   # AWK program above erroneously prepends '/' to C:/dos/paths
   # for these hosts.
   # for these hosts.
   case $host_os in
   case $host_os in
-    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+    mingw* | windows* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
       $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;;
       $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;;
   esac
   esac
   sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
   sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
@@ -2525,7 +2538,7 @@ bsdi[[45]]*)
   # libtool to hard-code these into programs
   # libtool to hard-code these into programs
   ;;
   ;;
 
 
-cygwin* | mingw* | pw32* | cegcc*)
+cygwin* | mingw* | windows* | pw32* | cegcc*)
   version_type=windows
   version_type=windows
   shrext_cmds=.dll
   shrext_cmds=.dll
   need_version=no
   need_version=no
@@ -2554,14 +2567,14 @@ cygwin* | mingw* | pw32* | cegcc*)
     cygwin*)
     cygwin*)
       # Cygwin DLLs use 'cyg' prefix rather than 'lib'
       # Cygwin DLLs use 'cyg' prefix rather than 'lib'
       #soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
       #soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
-      soname_spec='`echo $libname | sed -e 's/^lib//'`$shared_ext' # SDL customization
+      soname_spec='`echo $libname | sed -e 's/^lib//'`$shared_ext' # SDL customization.
 m4_if([$1], [],[
 m4_if([$1], [],[
       sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
       sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
       ;;
       ;;
-    mingw* | cegcc*)
+    mingw* | windows* | cegcc*)
       # MinGW DLLs use traditional 'lib' prefix
       # MinGW DLLs use traditional 'lib' prefix
       #soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
       #soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
-      soname_spec='`echo $libname | $SED -e 's/^lib//'`$shared_ext' # SDL customization
+      soname_spec='`echo $libname | $SED -e 's/^lib//'`$shared_ext' # SDL customization.
       ;;
       ;;
     pw32*)
     pw32*)
       # pw32 DLLs use 'pw' prefix rather than 'lib'
       # pw32 DLLs use 'pw' prefix rather than 'lib'
@@ -2571,14 +2584,14 @@ m4_if([$1], [],[
     dynamic_linker='Win32 ld.exe'
     dynamic_linker='Win32 ld.exe'
     ;;
     ;;
 
 
-  *,cl*)
-    # Native MSVC
+  *,cl* | *,icl*)
+    # Native MSVC or ICC
     libname_spec='$name'
     libname_spec='$name'
     soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
     soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
     library_names_spec='$libname.dll.lib'
     library_names_spec='$libname.dll.lib'
 
 
     case $build_os in
     case $build_os in
-    mingw*)
+    mingw* | windows*)
       sys_lib_search_path_spec=
       sys_lib_search_path_spec=
       lt_save_ifs=$IFS
       lt_save_ifs=$IFS
       IFS=';'
       IFS=';'
@@ -2628,7 +2641,7 @@ m4_if([$1], [],[
     ;;
     ;;
 
 
   *)
   *)
-    # Assume MSVC wrapper
+    # Assume MSVC and ICC wrapper
     library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'
     library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'
     dynamic_linker='Win32 ld.exe'
     dynamic_linker='Win32 ld.exe'
     ;;
     ;;
@@ -3267,7 +3280,7 @@ if test yes = "$GCC"; then
   # Check if gcc -print-prog-name=ld gives a path.
   # Check if gcc -print-prog-name=ld gives a path.
   AC_MSG_CHECKING([for ld used by $CC])
   AC_MSG_CHECKING([for ld used by $CC])
   case $host in
   case $host in
-  *-*-mingw*)
+  *-*-mingw* | *-*-windows*)
     # gcc leaves a trailing carriage return, which upsets mingw
     # gcc leaves a trailing carriage return, which upsets mingw
     ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
     ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
   *)
   *)
@@ -3376,7 +3389,7 @@ case $reload_flag in
 esac
 esac
 reload_cmds='$LD$reload_flag -o $output$reload_objs'
 reload_cmds='$LD$reload_flag -o $output$reload_objs'
 case $host_os in
 case $host_os in
-  cygwin* | mingw* | pw32* | cegcc*)
+  cygwin* | mingw* | windows* | pw32* | cegcc*)
     if test yes != "$GCC"; then
     if test yes != "$GCC"; then
       reload_cmds=false
       reload_cmds=false
     fi
     fi
@@ -3473,10 +3486,10 @@ cygwin*)
   # func_win32_libid is a shell function defined in ltmain.sh
   # func_win32_libid is a shell function defined in ltmain.sh
   lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
   lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
   lt_cv_file_magic_cmd='func_win32_libid'
   lt_cv_file_magic_cmd='func_win32_libid'
-  lt_cv_deplibs_check_method=pass_all # SDL customization
+  lt_cv_deplibs_check_method=pass_all # SDL customization.
   ;;
   ;;
 
 
-mingw* | pw32*)
+mingw* | windows* | pw32*)
   # Base MSYS/MinGW do not provide the 'file' command needed by
   # Base MSYS/MinGW do not provide the 'file' command needed by
   # func_win32_libid shell function, so use a weaker test based on 'objdump',
   # func_win32_libid shell function, so use a weaker test based on 'objdump',
   # unless we find 'file', for example because we are cross-compiling.
   # unless we find 'file', for example because we are cross-compiling.
@@ -3485,10 +3498,10 @@ mingw* | pw32*)
     lt_cv_file_magic_cmd='func_win32_libid'
     lt_cv_file_magic_cmd='func_win32_libid'
   else
   else
     # Keep this pattern in sync with the one in func_win32_libid.
     # Keep this pattern in sync with the one in func_win32_libid.
-    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64|pe-aarch64)'
     lt_cv_file_magic_cmd='$OBJDUMP -f'
     lt_cv_file_magic_cmd='$OBJDUMP -f'
   fi
   fi
-  lt_cv_deplibs_check_method=pass_all # SDL customization
+  lt_cv_deplibs_check_method=pass_all # SDL customization.
   ;;
   ;;
 
 
 cegcc*)
 cegcc*)
@@ -3641,7 +3654,7 @@ file_magic_glob=
 want_nocaseglob=no
 want_nocaseglob=no
 if test "$build" = "$host"; then
 if test "$build" = "$host"; then
   case $host_os in
   case $host_os in
-  mingw* | pw32*)
+  mingw* | windows* | pw32*)
     if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
     if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
       want_nocaseglob=yes
       want_nocaseglob=yes
     else
     else
@@ -3693,7 +3706,7 @@ else
 	# Tru64's nm complains that /dev/null is an invalid object file
 	# Tru64's nm complains that /dev/null is an invalid object file
 	# MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
 	# MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
 	case $build_os in
 	case $build_os in
-	mingw*) lt_bad_file=conftest.nm/nofile ;;
+	mingw* | windows*) lt_bad_file=conftest.nm/nofile ;;
 	*) lt_bad_file=/dev/null ;;
 	*) lt_bad_file=/dev/null ;;
 	esac
 	esac
 	case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
 	case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
@@ -3784,7 +3797,7 @@ lt_cv_sharedlib_from_linklib_cmd,
 [lt_cv_sharedlib_from_linklib_cmd='unknown'
 [lt_cv_sharedlib_from_linklib_cmd='unknown'
 
 
 case $host_os in
 case $host_os in
-cygwin* | mingw* | pw32* | cegcc*)
+cygwin* | mingw* | windows* | pw32* | cegcc*)
   # two different shell functions defined in ltmain.sh;
   # two different shell functions defined in ltmain.sh;
   # decide which one to use based on capabilities of $DLLTOOL
   # decide which one to use based on capabilities of $DLLTOOL
   case `$DLLTOOL --help 2>&1` in
   case `$DLLTOOL --help 2>&1` in
@@ -3929,7 +3942,7 @@ case $host_os in
 aix*)
 aix*)
   symcode='[[BCDT]]'
   symcode='[[BCDT]]'
   ;;
   ;;
-cygwin* | mingw* | pw32* | cegcc*)
+cygwin* | mingw* | windows* | pw32* | cegcc*)
   symcode='[[ABCDGISTW]]'
   symcode='[[ABCDGISTW]]'
   ;;
   ;;
 hpux*)
 hpux*)
@@ -4008,7 +4021,7 @@ $lt_c_name_lib_hook\
 # Handle CRLF in mingw tool chain
 # Handle CRLF in mingw tool chain
 opt_cr=
 opt_cr=
 case $build_os in
 case $build_os in
-mingw*)
+mingw* | windows*)
   opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
   opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
   ;;
   ;;
 esac
 esac
@@ -4023,7 +4036,7 @@ for ac_symprfx in "" "_"; do
   if test "$lt_cv_nm_interface" = "MS dumpbin"; then
   if test "$lt_cv_nm_interface" = "MS dumpbin"; then
     # Fake it for dumpbin and say T for any non-static function,
     # Fake it for dumpbin and say T for any non-static function,
     # D for any global variable and I for any imported variable.
     # D for any global variable and I for any imported variable.
-    # Also find C++ and __fastcall symbols from MSVC++,
+    # Also find C++ and __fastcall symbols from MSVC++ or ICC,
     # which start with @ or ?.
     # which start with @ or ?.
     lt_cv_sys_global_symbol_pipe="$AWK ['"\
     lt_cv_sys_global_symbol_pipe="$AWK ['"\
 "     {last_section=section; section=\$ 3};"\
 "     {last_section=section; section=\$ 3};"\
@@ -4059,7 +4072,7 @@ void nm_test_func(void){}
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }
 #endif
 #endif
-int main(){nm_test_var='a';nm_test_func();return(0);}
+int main(void){nm_test_var='a';nm_test_func();return(0);}
 _LT_EOF
 _LT_EOF
 
 
   if AC_TRY_EVAL(ac_compile); then
   if AC_TRY_EVAL(ac_compile); then
@@ -4235,7 +4248,7 @@ m4_if([$1], [CXX], [
     beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
     beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
       # PIC is the default for these OSes.
       # PIC is the default for these OSes.
       ;;
       ;;
-    mingw* | cygwin* | os2* | pw32* | cegcc*)
+    mingw* | windows* | cygwin* | os2* | pw32* | cegcc*)
       # This hack is so that the source file can tell whether it is being
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
       # built for inclusion in a dll (and should export symbols for example).
       # Although the cygwin gcc ignores -fPIC, still need this for old-style
       # Although the cygwin gcc ignores -fPIC, still need this for old-style
@@ -4311,7 +4324,7 @@ m4_if([$1], [CXX], [
 	  ;;
 	  ;;
 	esac
 	esac
 	;;
 	;;
-      mingw* | cygwin* | os2* | pw32* | cegcc*)
+      mingw* | windows* | cygwin* | os2* | pw32* | cegcc*)
 	# This hack is so that the source file can tell whether it is being
 	# This hack is so that the source file can tell whether it is being
 	# built for inclusion in a dll (and should export symbols for example).
 	# built for inclusion in a dll (and should export symbols for example).
 	m4_if([$1], [GCJ], [],
 	m4_if([$1], [GCJ], [],
@@ -4559,7 +4572,7 @@ m4_if([$1], [CXX], [
       # PIC is the default for these OSes.
       # PIC is the default for these OSes.
       ;;
       ;;
 
 
-    mingw* | cygwin* | pw32* | os2* | cegcc*)
+    mingw* | windows* | cygwin* | pw32* | os2* | cegcc*)
       # This hack is so that the source file can tell whether it is being
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
       # built for inclusion in a dll (and should export symbols for example).
       # Although the cygwin gcc ignores -fPIC, still need this for old-style
       # Although the cygwin gcc ignores -fPIC, still need this for old-style
@@ -4663,7 +4676,7 @@ m4_if([$1], [CXX], [
       esac
       esac
       ;;
       ;;
 
 
-    mingw* | cygwin* | pw32* | os2* | cegcc*)
+    mingw* | windows* | cygwin* | pw32* | os2* | cegcc*)
       # This hack is so that the source file can tell whether it is being
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
       # built for inclusion in a dll (and should export symbols for example).
       m4_if([$1], [GCJ], [],
       m4_if([$1], [GCJ], [],
@@ -4938,9 +4951,9 @@ m4_if([$1], [CXX], [
   pw32*)
   pw32*)
     _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds
     _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds
     ;;
     ;;
-  cygwin* | mingw* | cegcc*)
+  cygwin* | mingw* | windows* | cegcc*)
     case $cc_basename in
     case $cc_basename in
-    cl*)
+    cl* | icl*)
       _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
       _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
       ;;
       ;;
     *)
     *)
@@ -4996,16 +5009,16 @@ dnl Note also adjust exclude_expsyms for C++ above.
   extract_expsyms_cmds=
   extract_expsyms_cmds=
 
 
   case $host_os in
   case $host_os in
-  cygwin* | mingw* | pw32* | cegcc*)
-    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+  cygwin* | mingw* | windows* | pw32* | cegcc*)
+    # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time
     # When not using gcc, we currently assume that we are using
     # When not using gcc, we currently assume that we are using
-    # Microsoft Visual C++.
+    # Microsoft Visual C++ or Intel C++ Compiler.
     if test yes != "$GCC"; then
     if test yes != "$GCC"; then
       with_gnu_ld=no
       with_gnu_ld=no
     fi
     fi
     ;;
     ;;
   interix*)
   interix*)
-    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC)
     with_gnu_ld=yes
     with_gnu_ld=yes
     ;;
     ;;
   openbsd* | bitrig*)
   openbsd* | bitrig*)
@@ -5111,7 +5124,7 @@ _LT_EOF
       fi
       fi
       ;;
       ;;
 
 
-    cygwin* | mingw* | pw32* | cegcc*)
+    cygwin* | mingw* | windows* | pw32* | cegcc*)
       # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
       # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
       # as there is no search path for DLLs.
       # as there is no search path for DLLs.
       _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
       _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
@@ -5568,14 +5581,14 @@ _LT_EOF
       _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
       _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
       ;;
       ;;
 
 
-    cygwin* | mingw* | pw32* | cegcc*)
+    cygwin* | mingw* | windows* | pw32* | cegcc*)
       # When not using gcc, we currently assume that we are using
       # When not using gcc, we currently assume that we are using
-      # Microsoft Visual C++.
+      # Microsoft Visual C++ or Intel C++ Compiler.
       # hardcode_libdir_flag_spec is actually meaningless, as there is
       # hardcode_libdir_flag_spec is actually meaningless, as there is
       # no search path for DLLs.
       # no search path for DLLs.
       case $cc_basename in
       case $cc_basename in
-      cl*)
-	# Native MSVC
+      cl* | icl*)
+	# Native MSVC or ICC
 	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
 	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
 	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
 	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
 	_LT_TAGVAR(always_export_symbols, $1)=yes
 	_LT_TAGVAR(always_export_symbols, $1)=yes
@@ -5585,14 +5598,14 @@ _LT_EOF
 	# Tell ltmain to make .dll files, not .so files.
 	# Tell ltmain to make .dll files, not .so files.
 	shrext_cmds=.dll
 	shrext_cmds=.dll
 	# FIXME: Setting linknames here is a bad hack.
 	# FIXME: Setting linknames here is a bad hack.
-	_LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+	_LT_TAGVAR(archive_cmds, $1)='$CC -Fe $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
 	_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
 	_LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
             cp "$export_symbols" "$output_objdir/$soname.def";
             cp "$export_symbols" "$output_objdir/$soname.def";
             echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
             echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
           else
           else
             $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
             $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
           fi~
           fi~
-          $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+          $CC -Fe $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
           linknames='
           linknames='
 	# The linker will not automatically build a static lib if we build a DLL.
 	# The linker will not automatically build a static lib if we build a DLL.
 	# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
 	# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
@@ -5616,7 +5629,7 @@ _LT_EOF
           fi'
           fi'
 	;;
 	;;
       *)
       *)
-	# Assume MSVC wrapper
+	# Assume MSVC and ICC wrapper
 	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
 	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
 	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
 	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
 	# Tell ltmain to make .lib files, not .a files.
 	# Tell ltmain to make .lib files, not .a files.
@@ -6225,7 +6238,7 @@ _LT_TAGVAR(objext, $1)=$objext
 lt_simple_compile_test_code="int some_variable = 0;"
 lt_simple_compile_test_code="int some_variable = 0;"
 
 
 # Code to be used in simple link tests
 # Code to be used in simple link tests
-lt_simple_link_test_code='int main(){return(0);}'
+lt_simple_link_test_code='int main(void){return(0);}'
 
 
 _LT_TAG_COMPILER
 _LT_TAG_COMPILER
 # Save the default compiler, since it gets overwritten when the other
 # Save the default compiler, since it gets overwritten when the other
@@ -6435,7 +6448,7 @@ if test yes != "$_lt_caught_CXX_error"; then
       # Commands to make compiler produce verbose output that lists
       # Commands to make compiler produce verbose output that lists
       # what "hidden" libraries, object files and flags are used when
       # what "hidden" libraries, object files and flags are used when
       # linking a shared library.
       # linking a shared library.
-      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[[-]]L"'
 
 
     else
     else
       GXX=no
       GXX=no
@@ -6644,10 +6657,10 @@ if test yes != "$_lt_caught_CXX_error"; then
         esac
         esac
         ;;
         ;;
 
 
-      cygwin* | mingw* | pw32* | cegcc*)
+      cygwin* | mingw* | windows* | pw32* | cegcc*)
 	case $GXX,$cc_basename in
 	case $GXX,$cc_basename in
-	,cl* | no,cl*)
-	  # Native MSVC
+	,cl* | no,cl* | ,icl* | no,icl*)
+	  # Native MSVC or ICC
 	  # hardcode_libdir_flag_spec is actually meaningless, as there is
 	  # hardcode_libdir_flag_spec is actually meaningless, as there is
 	  # no search path for DLLs.
 	  # no search path for DLLs.
 	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
 	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
@@ -6811,7 +6824,7 @@ if test yes != "$_lt_caught_CXX_error"; then
             # explicitly linking system object files so we need to strip them
             # explicitly linking system object files so we need to strip them
             # from the output so that they don't get included in the library
             # from the output so that they don't get included in the library
             # dependencies.
             # dependencies.
-            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "[[-]]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
             ;;
             ;;
           *)
           *)
             if test yes = "$GXX"; then
             if test yes = "$GXX"; then
@@ -6876,7 +6889,7 @@ if test yes != "$_lt_caught_CXX_error"; then
 	    # explicitly linking system object files so we need to strip them
 	    # explicitly linking system object files so we need to strip them
 	    # from the output so that they don't get included in the library
 	    # from the output so that they don't get included in the library
 	    # dependencies.
 	    # dependencies.
-	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "[[-]]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 	    ;;
 	    ;;
           *)
           *)
 	    if test yes = "$GXX"; then
 	    if test yes = "$GXX"; then
@@ -7215,7 +7228,7 @@ if test yes != "$_lt_caught_CXX_error"; then
 	      # Commands to make compiler produce verbose output that lists
 	      # Commands to make compiler produce verbose output that lists
 	      # what "hidden" libraries, object files and flags are used when
 	      # what "hidden" libraries, object files and flags are used when
 	      # linking a shared library.
 	      # linking a shared library.
-	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[[-]]L"'
 
 
 	    else
 	    else
 	      # FIXME: insert proper C++ library support
 	      # FIXME: insert proper C++ library support
@@ -7299,7 +7312,7 @@ if test yes != "$_lt_caught_CXX_error"; then
 	        # Commands to make compiler produce verbose output that lists
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
 	        # what "hidden" libraries, object files and flags are used when
 	        # linking a shared library.
 	        # linking a shared library.
-	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[[-]]L"'
 	      else
 	      else
 	        # g++ 2.7 appears to require '-G' NOT '-shared' on this
 	        # g++ 2.7 appears to require '-G' NOT '-shared' on this
 	        # platform.
 	        # platform.
@@ -7310,7 +7323,7 @@ if test yes != "$_lt_caught_CXX_error"; then
 	        # Commands to make compiler produce verbose output that lists
 	        # Commands to make compiler produce verbose output that lists
 	        # what "hidden" libraries, object files and flags are used when
 	        # what "hidden" libraries, object files and flags are used when
 	        # linking a shared library.
 	        # linking a shared library.
-	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[[-]]L"'
 	      fi
 	      fi
 
 
 	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
 	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
@@ -8331,7 +8344,7 @@ AC_CACHE_VAL(lt_cv_to_host_file_cmd,
 [case $host in
 [case $host in
   *-*-mingw* )
   *-*-mingw* )
     case $build in
     case $build in
-      *-*-mingw* ) # actually msys
+      *-*-mingw* | *-*-windows* ) # actually msys
         lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
         lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
         ;;
         ;;
       *-*-cygwin* )
       *-*-cygwin* )
@@ -8344,7 +8357,7 @@ AC_CACHE_VAL(lt_cv_to_host_file_cmd,
     ;;
     ;;
   *-*-cygwin* )
   *-*-cygwin* )
     case $build in
     case $build in
-      *-*-mingw* ) # actually msys
+      *-*-mingw* | *-*-windows* ) # actually msys
         lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
         lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
         ;;
         ;;
       *-*-cygwin* )
       *-*-cygwin* )
@@ -8370,9 +8383,9 @@ AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
 [#assume ordinary cross tools, or native build.
 [#assume ordinary cross tools, or native build.
 lt_cv_to_tool_file_cmd=func_convert_file_noop
 lt_cv_to_tool_file_cmd=func_convert_file_noop
 case $host in
 case $host in
-  *-*-mingw* )
+  *-*-mingw* | *-*-windows* )
     case $build in
     case $build in
-      *-*-mingw* ) # actually msys
+      *-*-mingw* | *-*-windows* ) # actually msys
         lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
         lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
         ;;
         ;;
     esac
     esac

+ 1 - 1
Engine/lib/sdl/acinclude/ltoptions.m4

@@ -128,7 +128,7 @@ LT_OPTION_DEFINE([LT_INIT], [win32-dll],
 [enable_win32_dll=yes
 [enable_win32_dll=yes
 
 
 case $host in
 case $host in
-*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+*-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-cegcc*)
   AC_CHECK_TOOL(AS, as, false)
   AC_CHECK_TOOL(AS, as, false)
   AC_CHECK_TOOL(DLLTOOL, dlltool, false)
   AC_CHECK_TOOL(DLLTOOL, dlltool, false)
   AC_CHECK_TOOL(OBJDUMP, objdump, false)
   AC_CHECK_TOOL(OBJDUMP, objdump, false)

+ 1 - 0
Engine/lib/sdl/android-project-ant/AndroidManifest.xml

@@ -0,0 +1 @@
+../android-project/app/src/main/AndroidManifest.xml

+ 17 - 0
Engine/lib/sdl/android-project-ant/ant.properties

@@ -0,0 +1,17 @@
+# This file is used to override default values used by the Ant build system.
+#
+# This file must be checked into Version Control Systems, as it is
+# integral to the build system of your project.
+
+# This file is only used by the Ant script.
+
+# You can use this to override default values such as
+#  'source.dir' for the location of your java source folder and
+#  'out.dir' for the location of your output folder.
+
+# You can also use it define how the release builds are signed by declaring
+# the following properties:
+#  'key.store' for the location of your keystore and
+#  'key.alias' for the name of the key to use.
+# The password will be asked during the build when you use the 'release' target.
+

+ 17 - 0
Engine/lib/sdl/android-project-ant/build.properties

@@ -0,0 +1,17 @@
+# This file is used to override default values used by the Ant build system.
+# 
+# This file must be checked in Version Control Systems, as it is
+# integral to the build system of your project.
+
+# This file is only used by the Ant script.
+
+# You can use this to override default values such as
+#  'source.dir' for the location of your java source folder and
+#  'out.dir' for the location of your output folder.
+
+# You can also use it define how the release builds are signed by declaring
+# the following properties:
+#  'key.store' for the location of your keystore and
+#  'key.alias' for the name of the key to use.
+# The password will be asked during the build when you use the 'release' target.
+

+ 93 - 0
Engine/lib/sdl/android-project-ant/build.xml

@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- This should be changed to the name of your project -->
+<project name="SDLActivity" default="help">
+
+    <!-- The local.properties file is created and updated by the 'android' tool.
+         It contains the path to the SDK. It should *NOT* be checked into
+         Version Control Systems. -->
+    <property file="local.properties" />
+
+    <!-- The ant.properties file can be created by you. It is only edited by the
+         'android' tool to add properties to it.
+         This is the place to change some Ant specific build properties.
+         Here are some properties you may want to change/update:
+
+         source.dir
+             The name of the source directory. Default is 'src'.
+         out.dir
+             The name of the output directory. Default is 'bin'.
+
+         For other overridable properties, look at the beginning of the rules
+         files in the SDK, at tools/ant/build.xml
+
+         Properties related to the SDK location or the project target should
+         be updated using the 'android' tool with the 'update' action.
+
+         This file is an integral part of the build system for your
+         application and should be checked into Version Control Systems.
+
+         -->
+    <property file="ant.properties" />
+
+    <!-- if sdk.dir was not set from one of the property file, then
+         get it from the ANDROID_HOME env var.
+         This must be done before we load project.properties since
+         the proguard config can use sdk.dir -->
+    <property environment="env" />
+    <condition property="sdk.dir" value="${env.ANDROID_HOME}">
+        <isset property="env.ANDROID_HOME" />
+    </condition>
+
+    <!-- The project.properties file is created and updated by the 'android'
+         tool, as well as ADT.
+
+         This contains project specific properties such as project target, and library
+         dependencies. Lower level build properties are stored in ant.properties
+         (or in .classpath for Eclipse projects).
+
+         This file is an integral part of the build system for your
+         application and should be checked into Version Control Systems. -->
+    <loadproperties srcFile="project.properties" />
+
+    <!-- quick check on sdk.dir -->
+    <fail
+            message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
+            unless="sdk.dir"
+    />
+
+    <!--
+        Import per project custom build rules if present at the root of the project.
+        This is the place to put custom intermediary targets such as:
+            -pre-build
+            -pre-compile
+            -post-compile (This is typically used for code obfuscation.
+                           Compiled code location: ${out.classes.absolute.dir}
+                           If this is not done in place, override ${out.dex.input.absolute.dir})
+            -post-package
+            -post-build
+            -pre-clean
+    -->
+    <import file="custom_rules.xml" optional="true" />
+
+    <!-- Import the actual build file.
+
+         To customize existing targets, there are two options:
+         - Customize only one target:
+             - copy/paste the target into this file, *before* the
+               <import> task.
+             - customize it to your needs.
+         - Customize the whole content of build.xml
+             - copy/paste the content of the rules files (minus the top node)
+               into this file, replacing the <import> task.
+             - customize to your needs.
+
+         ***********************
+         ****** IMPORTANT ******
+         ***********************
+         In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+         in order to avoid having your file be overridden by tools such as "android update project"
+    -->
+    <!-- version-tag: 1 -->
+    <import file="${sdk.dir}/tools/ant/build.xml" />
+
+</project>

+ 11 - 0
Engine/lib/sdl/android-project-ant/default.properties

@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+# 
+# This file must be checked in Version Control Systems.
+# 
+# To customize properties used by the Ant build system use,
+# "build.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-16

+ 1 - 0
Engine/lib/sdl/android-project-ant/jni/Android.mk

@@ -0,0 +1 @@
+include $(call all-subdir-makefiles)

+ 10 - 0
Engine/lib/sdl/android-project-ant/jni/Application.mk

@@ -0,0 +1,10 @@
+
+# Uncomment this if you're using STL in your project
+# See CPLUSPLUS-SUPPORT.html in the NDK documentation for more information
+# APP_STL := stlport_static 
+
+APP_ABI := armeabi armeabi-v7a x86
+
+# Min SDK level
+APP_PLATFORM=android-10
+

+ 18 - 0
Engine/lib/sdl/android-project-ant/jni/src/Android.mk

@@ -0,0 +1,18 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := main
+
+SDL_PATH := ../SDL
+
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include
+
+# Add your application source files here...
+LOCAL_SRC_FILES := YourSourceHere.c
+
+LOCAL_SHARED_LIBRARIES := SDL2
+
+LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog
+
+include $(BUILD_SHARED_LIBRARY)

+ 12 - 0
Engine/lib/sdl/android-project-ant/jni/src/Android_static.mk

@@ -0,0 +1,12 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := main
+
+LOCAL_SRC_FILES := YourSourceHere.c
+
+LOCAL_STATIC_LIBRARIES := SDL2_static
+
+include $(BUILD_SHARED_LIBRARY)
+$(call import-module,SDL)LOCAL_PATH := $(call my-dir)

+ 20 - 0
Engine/lib/sdl/android-project-ant/proguard-project.txt

@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}

+ 14 - 0
Engine/lib/sdl/android-project-ant/project.properties

@@ -0,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-16

BIN
Engine/lib/sdl/android-project-ant/res/drawable-hdpi/ic_launcher.png


BIN
Engine/lib/sdl/android-project-ant/res/drawable-mdpi/ic_launcher.png


BIN
Engine/lib/sdl/android-project-ant/res/drawable-xhdpi/ic_launcher.png


BIN
Engine/lib/sdl/android-project-ant/res/drawable-xxhdpi/ic_launcher.png


+ 13 - 0
Engine/lib/sdl/android-project-ant/res/layout/main.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    >
+<TextView  
+    android:layout_width="fill_parent" 
+    android:layout_height="wrap_content" 
+    android:text="Hello World, SDLActivity"
+    />
+</LinearLayout>
+

+ 4 - 0
Engine/lib/sdl/android-project-ant/res/values/strings.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">SDL App</string>
+</resources>

+ 1 - 0
Engine/lib/sdl/android-project-ant/src

@@ -0,0 +1 @@
+../android-project/app/src/main/java

+ 81 - 0
Engine/lib/sdl/android-project/app/proguard-rules.pro

@@ -15,3 +15,84 @@
 #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
 #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
 #   public *;
 #   public *;
 #}
 #}
+
+-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.SDLInputConnection {
+    void nativeCommitText(java.lang.String, int);
+    void nativeGenerateScancodeForUnichar(char);
+}
+
+-keep,includedescriptorclasses class org.libsdl.app.SDLActivity {
+    # for some reason these aren't compatible with allowoptimization modifier
+    boolean supportsRelativeMouse();
+    void setWindowStyle(boolean);
+}
+
+-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.SDLActivity {
+    java.lang.String nativeGetHint(java.lang.String); # Java-side doesn't use this, so it gets minified, but C-side still tries to register it
+    boolean onNativeSoftReturnKey();
+    void onNativeKeyboardFocusLost();
+    boolean isScreenKeyboardShown();
+    android.util.DisplayMetrics getDisplayDPI();
+    java.lang.String clipboardGetText();
+    boolean clipboardHasText();
+    void clipboardSetText(java.lang.String);
+    int createCustomCursor(int[], int, int, int, int);
+    void destroyCustomCursor(int);
+    android.content.Context getContext();
+    boolean getManifestEnvironmentVariables();
+    android.view.Surface getNativeSurface();
+    void initTouch();
+    boolean isAndroidTV();
+    boolean isChromebook();
+    boolean isDeXMode();
+    boolean isTablet();
+    void manualBackButton();
+    int messageboxShowMessageBox(int, java.lang.String, java.lang.String, int[], int[], java.lang.String[], int[]);
+    void minimizeWindow();
+    int openURL(java.lang.String);
+    void requestPermission(java.lang.String, int);
+    int showToast(java.lang.String, int, int, int, int);
+    boolean sendMessage(int, int);
+    boolean setActivityTitle(java.lang.String);
+    boolean setCustomCursor(int);
+    void setOrientation(int, int, boolean, java.lang.String);
+    boolean setRelativeMouseEnabled(boolean);
+    boolean setSystemCursor(int);
+    boolean shouldMinimizeOnFocusLoss();
+    boolean showTextInput(int, int, int, int);
+}
+
+-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.HIDDeviceManager {
+    boolean initialize(boolean, boolean);
+    boolean openDevice(int);
+    int sendOutputReport(int, byte[]);
+    int sendFeatureReport(int, byte[]);
+    boolean getFeatureReport(int, byte[]);
+    void closeDevice(int);
+}
+
+-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.SDLAudioManager {
+    int[] getAudioOutputDevices();
+    int[] getAudioInputDevices();
+    int[] audioOpen(int, int, int, int, int);
+    void audioWriteFloatBuffer(float[]);
+    void audioWriteShortBuffer(short[]);
+    void audioWriteByteBuffer(byte[]);
+    void audioClose();
+    int[] captureOpen(int, int, int, int, int);
+    int captureReadFloatBuffer(float[], boolean);
+    int captureReadShortBuffer(short[], boolean);
+    int captureReadByteBuffer(byte[], boolean);
+    void captureClose();
+    void audioSetThreadPriority(boolean, int);
+    native int nativeSetupJNI();
+    native void removeAudioDevice(boolean, int);
+    native void addAudioDevice(boolean, int);
+}
+
+-keep,includedescriptorclasses,allowoptimization class org.libsdl.app.SDLControllerManager {
+    void pollInputDevices();
+    void pollHapticDevices();
+    void hapticRun(int, float, int);
+    void hapticStop(int);
+}

+ 1 - 1
Engine/lib/sdl/android-project/app/src/main/AndroidManifest.xml

@@ -62,7 +62,7 @@
     <application android:label="@string/app_name"
     <application android:label="@string/app_name"
         android:icon="@mipmap/ic_launcher"
         android:icon="@mipmap/ic_launcher"
         android:allowBackup="true"
         android:allowBackup="true"
-        android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+        android:theme="@style/AppTheme"
         android:hardwareAccelerated="true" >
         android:hardwareAccelerated="true" >
 
 
         <!-- Example of setting SDL hints from AndroidManifest.xml:
         <!-- Example of setting SDL hints from AndroidManifest.xml:

+ 16 - 1
Engine/lib/sdl/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java

@@ -273,9 +273,11 @@ public class HIDDeviceManager {
         final int XB1_IFACE_SUBCLASS = 71;
         final int XB1_IFACE_SUBCLASS = 71;
         final int XB1_IFACE_PROTOCOL = 208;
         final int XB1_IFACE_PROTOCOL = 208;
         final int[] SUPPORTED_VENDORS = {
         final int[] SUPPORTED_VENDORS = {
+            0x03f0, // HP
             0x044f, // Thrustmaster
             0x044f, // Thrustmaster
             0x045e, // Microsoft
             0x045e, // Microsoft
             0x0738, // Mad Catz
             0x0738, // Mad Catz
+            0x0b05, // ASUS
             0x0e6f, // PDP
             0x0e6f, // PDP
             0x0f0d, // Hori
             0x0f0d, // Hori
             0x10f5, // Turtle Beach
             0x10f5, // Turtle Beach
@@ -284,6 +286,7 @@ public class HIDDeviceManager {
             0x24c6, // PowerA
             0x24c6, // PowerA
             0x2dc8, // 8BitDo
             0x2dc8, // 8BitDo
             0x2e24, // Hyperkin
             0x2e24, // Hyperkin
+            0x3537, // GameSir
         };
         };
 
 
         if (usbInterface.getId() == 0 &&
         if (usbInterface.getId() == 0 &&
@@ -357,6 +360,12 @@ public class HIDDeviceManager {
     private void initializeBluetooth() {
     private void initializeBluetooth() {
         Log.d(TAG, "Initializing Bluetooth");
         Log.d(TAG, "Initializing Bluetooth");
 
 
+        if (Build.VERSION.SDK_INT >= 31 /* Android 12  */ &&
+            mContext.getPackageManager().checkPermission(android.Manifest.permission.BLUETOOTH_CONNECT, mContext.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
+            Log.d(TAG, "Couldn't initialize Bluetooth, missing android.permission.BLUETOOTH_CONNECT");
+            return;
+        }
+
         if (Build.VERSION.SDK_INT <= 30 /* Android 11.0 (R) */ &&
         if (Build.VERSION.SDK_INT <= 30 /* Android 11.0 (R) */ &&
             mContext.getPackageManager().checkPermission(android.Manifest.permission.BLUETOOTH, mContext.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
             mContext.getPackageManager().checkPermission(android.Manifest.permission.BLUETOOTH, mContext.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
             Log.d(TAG, "Couldn't initialize Bluetooth, missing android.permission.BLUETOOTH");
             Log.d(TAG, "Couldn't initialize Bluetooth, missing android.permission.BLUETOOTH");
@@ -582,7 +591,13 @@ public class HIDDeviceManager {
                 } else {
                 } else {
                     flags = 0;
                     flags = 0;
                 }
                 }
-                mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, new Intent(HIDDeviceManager.ACTION_USB_PERMISSION), flags));
+                if (Build.VERSION.SDK_INT >= 33 /* Android 14.0 (U) */) {
+                   Intent intent = new Intent(HIDDeviceManager.ACTION_USB_PERMISSION);
+                   intent.setPackage(mContext.getPackageName());
+                   mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, intent, flags));
+               } else {
+                   mUsbManager.requestPermission(usbDevice, PendingIntent.getBroadcast(mContext, 0, new Intent(HIDDeviceManager.ACTION_USB_PERMISSION), flags));
+               }
             } catch (Exception e) {
             } catch (Exception e) {
                 Log.v(TAG, "Couldn't request permission for USB device " + usbDevice);
                 Log.v(TAG, "Couldn't request permission for USB device " + usbDevice);
                 HIDDeviceOpenResult(deviceID, false);
                 HIDDeviceOpenResult(deviceID, false);

+ 9 - 5
Engine/lib/sdl/android-project/app/src/main/java/org/libsdl/app/SDL.java

@@ -38,6 +38,10 @@ public class SDL {
     }
     }
 
 
     public static void loadLibrary(String libraryName) throws UnsatisfiedLinkError, SecurityException, NullPointerException {
     public static void loadLibrary(String libraryName) throws UnsatisfiedLinkError, SecurityException, NullPointerException {
+        loadLibrary(libraryName, mContext);
+    }
+
+    public static void loadLibrary(String libraryName, Context context) throws UnsatisfiedLinkError, SecurityException, NullPointerException {
 
 
         if (libraryName == null) {
         if (libraryName == null) {
             throw new NullPointerException("No library name provided.");
             throw new NullPointerException("No library name provided.");
@@ -53,10 +57,10 @@ public class SDL {
             // To use ReLinker, just add it as a dependency.  For more information, see 
             // To use ReLinker, just add it as a dependency.  For more information, see 
             // https://github.com/KeepSafe/ReLinker for ReLinker's repository.
             // https://github.com/KeepSafe/ReLinker for ReLinker's repository.
             //
             //
-            Class<?> relinkClass = mContext.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker");
-            Class<?> relinkListenerClass = mContext.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker$LoadListener");
-            Class<?> contextClass = mContext.getClassLoader().loadClass("android.content.Context");
-            Class<?> stringClass = mContext.getClassLoader().loadClass("java.lang.String");
+            Class<?> relinkClass = context.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker");
+            Class<?> relinkListenerClass = context.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker$LoadListener");
+            Class<?> contextClass = context.getClassLoader().loadClass("android.content.Context");
+            Class<?> stringClass = context.getClassLoader().loadClass("java.lang.String");
 
 
             // Get a 'force' instance of the ReLinker, so we can ensure libraries are reinstalled if 
             // Get a 'force' instance of the ReLinker, so we can ensure libraries are reinstalled if 
             // they've changed during updates.
             // they've changed during updates.
@@ -66,7 +70,7 @@ public class SDL {
 
 
             // Actually load the library!
             // Actually load the library!
             Method loadMethod = relinkInstanceClass.getDeclaredMethod("loadLibrary", contextClass, stringClass, stringClass, relinkListenerClass);
             Method loadMethod = relinkInstanceClass.getDeclaredMethod("loadLibrary", contextClass, stringClass, stringClass, relinkListenerClass);
-            loadMethod.invoke(relinkInstance, mContext, libraryName, null, null);
+            loadMethod.invoke(relinkInstance, context, libraryName, null, null);
         }
         }
         catch (final Throwable e) {
         catch (final Throwable e) {
             // Fall back
             // Fall back

+ 12 - 9
Engine/lib/sdl/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java

@@ -60,8 +60,8 @@ import java.util.Locale;
 public class SDLActivity extends Activity implements View.OnSystemUiVisibilityChangeListener {
 public class SDLActivity extends Activity implements View.OnSystemUiVisibilityChangeListener {
     private static final String TAG = "SDL";
     private static final String TAG = "SDL";
     private static final int SDL_MAJOR_VERSION = 2;
     private static final int SDL_MAJOR_VERSION = 2;
-    private static final int SDL_MINOR_VERSION = 28;
-    private static final int SDL_MICRO_VERSION = 4;
+    private static final int SDL_MINOR_VERSION = 32;
+    private static final int SDL_MICRO_VERSION = 6;
 /*
 /*
     // Display InputType.SOURCE/CLASS of events and devices
     // Display InputType.SOURCE/CLASS of events and devices
     //
     //
@@ -89,7 +89,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
                 | InputDevice.SOURCE_CLASS_POSITION
                 | InputDevice.SOURCE_CLASS_POSITION
                 | InputDevice.SOURCE_CLASS_TRACKBALL);
                 | InputDevice.SOURCE_CLASS_TRACKBALL);
 
 
-        if (s2 != 0) cls += "Some_Unkown";
+        if (s2 != 0) cls += "Some_Unknown";
 
 
         s2 = s_copy & InputDevice.SOURCE_ANY; // keep source only, no class;
         s2 = s_copy & InputDevice.SOURCE_ANY; // keep source only, no class;
 
 
@@ -163,7 +163,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
         if (s == FLAG_TAINTED) src += " FLAG_TAINTED";
         if (s == FLAG_TAINTED) src += " FLAG_TAINTED";
         s2 &= ~FLAG_TAINTED;
         s2 &= ~FLAG_TAINTED;
 
 
-        if (s2 != 0) src += " Some_Unkown";
+        if (s2 != 0) src += " Some_Unknown";
 
 
         Log.v(TAG, prefix + "int=" + s_copy + " CLASS={" + cls + " } source(s):" + src);
         Log.v(TAG, prefix + "int=" + s_copy + " CLASS={" + cls + " } source(s):" + src);
     }
     }
@@ -281,7 +281,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
     // Load the .so
     // Load the .so
     public void loadLibraries() {
     public void loadLibraries() {
        for (String lib : getLibraries()) {
        for (String lib : getLibraries()) {
-          SDL.loadLibrary(lib);
+          SDL.loadLibrary(lib, this);
        }
        }
     }
     }
 
 
@@ -790,6 +790,9 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
                                 window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
                                 window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
                                 SDLActivity.mFullscreenModeActive = false;
                                 SDLActivity.mFullscreenModeActive = false;
                             }
                             }
+                            if (Build.VERSION.SDK_INT >= 28 /* Android 9 (Pie) */) {
+                                window.getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
+                            }
                         }
                         }
                     } else {
                     } else {
                         Log.e(TAG, "error handling message, getContext() returned no Activity");
                         Log.e(TAG, "error handling message, getContext() returned no Activity");
@@ -995,8 +998,8 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
         /* No valid hint, nothing is explicitly allowed */
         /* No valid hint, nothing is explicitly allowed */
         if (!is_portrait_allowed && !is_landscape_allowed) {
         if (!is_portrait_allowed && !is_landscape_allowed) {
             if (resizable) {
             if (resizable) {
-                /* All orientations are allowed */
-                req = ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR;
+                /* All orientations are allowed, respecting user orientation lock setting */
+                req = ActivityInfo.SCREEN_ORIENTATION_FULL_USER;
             } else {
             } else {
                 /* Fixed window and nothing specified. Get orientation from w/h of created window */
                 /* Fixed window and nothing specified. Get orientation from w/h of created window */
                 req = (w > h ? ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE : ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
                 req = (w > h ? ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE : ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
@@ -1005,8 +1008,8 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
             /* At least one orientation is allowed */
             /* At least one orientation is allowed */
             if (resizable) {
             if (resizable) {
                 if (is_portrait_allowed && is_landscape_allowed) {
                 if (is_portrait_allowed && is_landscape_allowed) {
-                    /* hint allows both landscape and portrait, promote to full sensor */
-                    req = ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR;
+                    /* hint allows both landscape and portrait, promote to full user */
+                    req = ActivityInfo.SCREEN_ORIENTATION_FULL_USER;
                 } else {
                 } else {
                     /* Use the only one allowed "orientation" */
                     /* Use the only one allowed "orientation" */
                     req = (is_landscape_allowed ? orientation_landscape : orientation_portrait);
                     req = (is_landscape_allowed ? orientation_landscape : orientation_portrait);

+ 9 - 7
Engine/lib/sdl/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java

@@ -546,13 +546,15 @@ class SDLHapticHandler {
             if (haptic == null) {
             if (haptic == null) {
                 InputDevice device = InputDevice.getDevice(deviceIds[i]);
                 InputDevice device = InputDevice.getDevice(deviceIds[i]);
                 Vibrator vib = device.getVibrator();
                 Vibrator vib = device.getVibrator();
-                if (vib.hasVibrator()) {
-                    haptic = new SDLHaptic();
-                    haptic.device_id = deviceIds[i];
-                    haptic.name = device.getName();
-                    haptic.vib = vib;
-                    mHaptics.add(haptic);
-                    SDLControllerManager.nativeAddHaptic(haptic.device_id, haptic.name);
+                if (vib != null) {
+                    if (vib.hasVibrator()) {
+                        haptic = new SDLHaptic();
+                        haptic.device_id = deviceIds[i];
+                        haptic.name = device.getName();
+                        haptic.vib = vib;
+                        mHaptics.add(haptic);
+                        SDLControllerManager.nativeAddHaptic(haptic.device_id, haptic.name);
+                    }
                 }
                 }
             }
             }
         }
         }

+ 2 - 3
Engine/lib/sdl/android-project/app/src/main/res/values/styles.xml

@@ -1,8 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
 <resources>
 <resources>
-
     <!-- Base application theme. -->
     <!-- Base application theme. -->
-    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
+    <style name="AppTheme" parent="android:Theme.NoTitleBar.Fullscreen">
         <!-- Customize your theme here. -->
         <!-- Customize your theme here. -->
     </style>
     </style>
-
 </resources>
 </resources>

+ 2 - 1
Engine/lib/sdl/build-scripts/androidbuild.sh

@@ -80,7 +80,8 @@ do
     cd $folder
     cd $folder
 done
 done
 
 
-ACTIVITY="${folder}Activity"
+# Uppercase the first char in the activity class name because it's Java
+ACTIVITY="$(echo $folder | awk '{$1=toupper(substr($1,0,1))substr($1,2)}1')Activity"
 sed -i -e "s|\"SDLActivity\"|\"$ACTIVITY\"|g" $BUILDPATH/app/src/main/AndroidManifest.xml
 sed -i -e "s|\"SDLActivity\"|\"$ACTIVITY\"|g" $BUILDPATH/app/src/main/AndroidManifest.xml
 
 
 # Fill in a default Activity
 # Fill in a default Activity

+ 1470 - 0
Engine/lib/sdl/build-scripts/build-release.py

@@ -0,0 +1,1470 @@
+#!/usr/bin/env python3
+
+"""
+This script is shared between SDL2, SDL3, and all satellite libraries.
+Don't specialize this script for doing project-specific modifications.
+Rather, modify release-info.json.
+"""
+
+import argparse
+import collections
+import dataclasses
+from collections.abc import Callable
+import contextlib
+import datetime
+import fnmatch
+import glob
+import io
+import json
+import logging
+import multiprocessing
+import os
+from pathlib import Path
+import platform
+import re
+import shlex
+import shutil
+import subprocess
+import sys
+import tarfile
+import tempfile
+import textwrap
+import typing
+import zipfile
+
+
+logger = logging.getLogger(__name__)
+GIT_HASH_FILENAME = ".git-hash"
+REVISION_TXT = "REVISION.txt"
+
+
+def safe_isotime_to_datetime(str_isotime: str) -> datetime.datetime:
+    try:
+        return datetime.datetime.fromisoformat(str_isotime)
+    except ValueError:
+        pass
+    logger.warning("Invalid iso time: %s", str_isotime)
+    if str_isotime[-6:-5] in ("+", "-"):
+        # Commits can have isotime with invalid timezone offset (e.g. "2021-07-04T20:01:40+32:00")
+        modified_str_isotime = str_isotime[:-6] + "+00:00"
+        try:
+            return datetime.datetime.fromisoformat(modified_str_isotime)
+        except ValueError:
+            pass
+    raise ValueError(f"Invalid isotime: {str_isotime}")
+
+
+def arc_join(*parts: list[str]) -> str:
+    assert all(p[:1] != "/" and p[-1:] != "/" for p in parts), f"None of {parts} may start or end with '/'"
+    return "/".join(p for p in parts if p)
+
+
[email protected](frozen=True)
+class VsArchPlatformConfig:
+    arch: str
+    configuration: str
+    platform: str
+
+    def extra_context(self):
+        return {
+            "ARCH": self.arch,
+            "CONFIGURATION": self.configuration,
+            "PLATFORM": self.platform,
+        }
+
+
[email protected]
+def chdir(path):
+    original_cwd = os.getcwd()
+    try:
+        os.chdir(path)
+        yield
+    finally:
+        os.chdir(original_cwd)
+
+
+class Executer:
+    def __init__(self, root: Path, dry: bool=False):
+        self.root = root
+        self.dry = dry
+
+    def run(self, cmd, cwd=None, env=None):
+        logger.info("Executing args=%r", cmd)
+        sys.stdout.flush()
+        if not self.dry:
+            subprocess.check_call(cmd, cwd=cwd or self.root, env=env, text=True)
+
+    def check_output(self, cmd, cwd=None, dry_out=None, env=None, text=True):
+        logger.info("Executing args=%r", cmd)
+        sys.stdout.flush()
+        if self.dry:
+            return dry_out
+        return subprocess.check_output(cmd, cwd=cwd or self.root, env=env, text=text)
+
+
+class SectionPrinter:
+    @contextlib.contextmanager
+    def group(self, title: str):
+        print(f"{title}:")
+        yield
+
+
+class GitHubSectionPrinter(SectionPrinter):
+    def __init__(self):
+        super().__init__()
+        self.in_group = False
+
+    @contextlib.contextmanager
+    def group(self, title: str):
+        print(f"::group::{title}")
+        assert not self.in_group, "Can enter a group only once"
+        self.in_group = True
+        yield
+        self.in_group = False
+        print("::endgroup::")
+
+
+class VisualStudio:
+    def __init__(self, executer: Executer, year: typing.Optional[str]=None):
+        self.executer = executer
+        self.vsdevcmd = self.find_vsdevcmd(year)
+        self.msbuild = self.find_msbuild()
+
+    @property
+    def dry(self) -> bool:
+        return self.executer.dry
+
+    VS_YEAR_TO_VERSION = {
+        "2022": 17,
+        "2019": 16,
+        "2017": 15,
+        "2015": 14,
+        "2013": 12,
+    }
+
+    def find_vsdevcmd(self, year: typing.Optional[str]=None) -> typing.Optional[Path]:
+        vswhere_spec = ["-latest"]
+        if year is not None:
+            try:
+                version = self.VS_YEAR_TO_VERSION[year]
+            except KeyError:
+                logger.error("Invalid Visual Studio year")
+                return None
+            vswhere_spec.extend(["-version", f"[{version},{version+1})"])
+        vswhere_cmd = ["vswhere"] + vswhere_spec + ["-property", "installationPath"]
+        vs_install_path = Path(self.executer.check_output(vswhere_cmd, dry_out="/tmp").strip())
+        logger.info("VS install_path = %s", vs_install_path)
+        assert vs_install_path.is_dir(), "VS installation path does not exist"
+        vsdevcmd_path = vs_install_path / "Common7/Tools/vsdevcmd.bat"
+        logger.info("vsdevcmd path = %s", vsdevcmd_path)
+        if self.dry:
+            vsdevcmd_path.parent.mkdir(parents=True, exist_ok=True)
+            vsdevcmd_path.touch(exist_ok=True)
+        assert vsdevcmd_path.is_file(), "vsdevcmd.bat batch file does not exist"
+        return vsdevcmd_path
+
+    def find_msbuild(self) -> typing.Optional[Path]:
+        vswhere_cmd = ["vswhere", "-latest", "-requires", "Microsoft.Component.MSBuild", "-find", r"MSBuild\**\Bin\MSBuild.exe"]
+        msbuild_path = Path(self.executer.check_output(vswhere_cmd, dry_out="/tmp/MSBuild.exe").strip())
+        logger.info("MSBuild path = %s", msbuild_path)
+        if self.dry:
+            msbuild_path.parent.mkdir(parents=True, exist_ok=True)
+            msbuild_path.touch(exist_ok=True)
+        assert msbuild_path.is_file(), "MSBuild.exe does not exist"
+        return msbuild_path
+
+    def build(self, arch_platform: VsArchPlatformConfig, projects: list[Path]):
+        assert projects, "Need at least one project to build"
+
+        vsdev_cmd_str = f"\"{self.vsdevcmd}\" -arch={arch_platform.arch}"
+        msbuild_cmd_str = " && ".join([f"\"{self.msbuild}\" \"{project}\" /m /p:BuildInParallel=true /p:Platform={arch_platform.platform} /p:Configuration={arch_platform.configuration}" for project in projects])
+        bat_contents = f"{vsdev_cmd_str} && {msbuild_cmd_str}\n"
+        bat_path = Path(tempfile.gettempdir()) / "cmd.bat"
+        with bat_path.open("w") as f:
+            f.write(bat_contents)
+
+        logger.info("Running cmd.exe script (%s): %s", bat_path, bat_contents)
+        cmd = ["cmd.exe", "/D", "/E:ON", "/V:OFF", "/S", "/C", f"CALL {str(bat_path)}"]
+        self.executer.run(cmd)
+
+
+class Archiver:
+    def __init__(self, zip_path: typing.Optional[Path]=None, tgz_path: typing.Optional[Path]=None, txz_path: typing.Optional[Path]=None):
+        self._zip_files = []
+        self._tar_files = []
+        self._added_files = set()
+        if zip_path:
+            self._zip_files.append(zipfile.ZipFile(zip_path, "w", compression=zipfile.ZIP_DEFLATED))
+        if tgz_path:
+            self._tar_files.append(tarfile.open(tgz_path, "w:gz"))
+        if txz_path:
+            self._tar_files.append(tarfile.open(txz_path, "w:xz"))
+
+    @property
+    def added_files(self) -> set[str]:
+        return self._added_files
+
+    def add_file_data(self, arcpath: str, data: bytes, mode: int, time: datetime.datetime):
+        for zf in self._zip_files:
+            file_data_time = (time.year, time.month, time.day, time.hour, time.minute, time.second)
+            zip_info = zipfile.ZipInfo(filename=arcpath, date_time=file_data_time)
+            zip_info.external_attr = mode << 16
+            zip_info.compress_type = zipfile.ZIP_DEFLATED
+            zf.writestr(zip_info, data=data)
+        for tf in self._tar_files:
+            tar_info = tarfile.TarInfo(arcpath)
+            tar_info.type = tarfile.REGTYPE
+            tar_info.mode = mode
+            tar_info.size = len(data)
+            tar_info.mtime = int(time.timestamp())
+            tf.addfile(tar_info, fileobj=io.BytesIO(data))
+
+        self._added_files.add(arcpath)
+
+    def add_symlink(self, arcpath: str, target: str, time: datetime.datetime, files_for_zip):
+        logger.debug("Adding symlink (target=%r) -> %s", target, arcpath)
+        for zf in self._zip_files:
+            file_data_time = (time.year, time.month, time.day, time.hour, time.minute, time.second)
+            for f in files_for_zip:
+                zip_info = zipfile.ZipInfo(filename=f["arcpath"], date_time=file_data_time)
+                zip_info.external_attr = f["mode"] << 16
+                zip_info.compress_type = zipfile.ZIP_DEFLATED
+                zf.writestr(zip_info, data=f["data"])
+        for tf in self._tar_files:
+            tar_info = tarfile.TarInfo(arcpath)
+            tar_info.type = tarfile.SYMTYPE
+            tar_info.mode = 0o777
+            tar_info.mtime = int(time.timestamp())
+            tar_info.linkname = target
+            tf.addfile(tar_info)
+
+        self._added_files.update(f["arcpath"] for f in files_for_zip)
+
+    def add_git_hash(self, arcdir: str, commit: str, time: datetime.datetime):
+        arcpath = arc_join(arcdir, GIT_HASH_FILENAME)
+        data = f"{commit}\n".encode()
+        self.add_file_data(arcpath=arcpath, data=data, mode=0o100644, time=time)
+
+    def add_file_path(self, arcpath: str, path: Path):
+        assert path.is_file(), f"{path} should be a file"
+        logger.debug("Adding %s -> %s", path, arcpath)
+        for zf in self._zip_files:
+            zf.write(path, arcname=arcpath)
+        for tf in self._tar_files:
+            tf.add(path, arcname=arcpath)
+
+    def add_file_directory(self, arcdirpath: str, dirpath: Path):
+        assert dirpath.is_dir()
+        if arcdirpath and arcdirpath[-1:] != "/":
+            arcdirpath += "/"
+        for f in dirpath.iterdir():
+            if f.is_file():
+                arcpath = f"{arcdirpath}{f.name}"
+                logger.debug("Adding %s to %s", f, arcpath)
+                self.add_file_path(arcpath=arcpath, path=f)
+
+    def close(self):
+        # Archiver is intentionally made invalid after this function
+        del self._zip_files
+        self._zip_files = None
+        del self._tar_files
+        self._tar_files = None
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, type, value, traceback):
+        self.close()
+
+
+class NodeInArchive:
+    def __init__(self, arcpath: str, path: typing.Optional[Path]=None, data: typing.Optional[bytes]=None, mode: typing.Optional[int]=None, symtarget: typing.Optional[str]=None, time: typing.Optional[datetime.datetime]=None, directory: bool=False):
+        self.arcpath = arcpath
+        self.path = path
+        self.data = data
+        self.mode = mode
+        self.symtarget = symtarget
+        self.time = time
+        self.directory = directory
+
+    @classmethod
+    def from_fs(cls, arcpath: str, path: Path, mode: int=0o100644, time: typing.Optional[datetime.datetime]=None) -> "NodeInArchive":
+        if time is None:
+            time = datetime.datetime.fromtimestamp(os.stat(path).st_mtime)
+        return cls(arcpath=arcpath, path=path, mode=mode)
+
+    @classmethod
+    def from_data(cls, arcpath: str, data: bytes, time: datetime.datetime) -> "NodeInArchive":
+        return cls(arcpath=arcpath, data=data, time=time, mode=0o100644)
+
+    @classmethod
+    def from_text(cls, arcpath: str, text: str, time: datetime.datetime) -> "NodeInArchive":
+        return cls.from_data(arcpath=arcpath, data=text.encode(), time=time)
+
+    @classmethod
+    def from_symlink(cls, arcpath: str, symtarget: str) -> "NodeInArchive":
+        return cls(arcpath=arcpath, symtarget=symtarget)
+
+    @classmethod
+    def from_directory(cls, arcpath: str) -> "NodeInArchive":
+        return cls(arcpath=arcpath, directory=True)
+
+    def __repr__(self) -> str:
+        return f"<{type(self).__name__}:arcpath={self.arcpath},path='{str(self.path)}',len(data)={len(self.data) if self.data else 'n/a'},directory={self.directory},symtarget={self.symtarget}>"
+
+
+def configure_file(path: Path, context: dict[str, str]) -> bytes:
+    text = path.read_text()
+    return configure_text(text, context=context).encode()
+
+
+def configure_text(text: str, context: dict[str, str]) -> str:
+    original_text = text
+    for txt, repl in context.items():
+        text = text.replace(f"@<@{txt}@>@", repl)
+    success = all(thing not in text for thing in ("@<@", "@>@"))
+    if not success:
+        raise ValueError(f"Failed to configure {repr(original_text)}")
+    return text
+
+
+def configure_text_list(text_list: list[str], context: dict[str, str]) -> list[str]:
+    return [configure_text(text=e, context=context) for e in text_list]
+
+
+class ArchiveFileTree:
+    def __init__(self):
+        self._tree: dict[str, NodeInArchive] = {}
+
+    def add_file(self, file: NodeInArchive):
+        self._tree[file.arcpath] = file
+
+    def get_latest_mod_time(self) -> datetime.datetime:
+        return max(item.time for item in self._tree.values() if item.time)
+
+    def add_to_archiver(self, archive_base: str, archiver: Archiver):
+        remaining_symlinks = set()
+        added_files = dict()
+
+        def calculate_symlink_target(s: NodeInArchive) -> str:
+            dest_dir = os.path.dirname(s.arcpath)
+            if dest_dir:
+                dest_dir += "/"
+            target = dest_dir + s.symtarget
+            while True:
+                new_target, n = re.subn(r"([^/]+/+[.]{2}/)", "", target)
+                target = new_target
+                if not n:
+                    break
+            return target
+
+        # Add files in first pass
+        for arcpath, node in self._tree.items():
+            assert node is not None, f"{arcpath} -> node"
+            if node.data is not None:
+                archiver.add_file_data(arcpath=arc_join(archive_base, arcpath), data=node.data, time=node.time, mode=node.mode)
+                assert node.arcpath is not None, f"{node=}"
+                added_files[node.arcpath] = node
+            elif node.path is not None:
+                archiver.add_file_path(arcpath=arc_join(archive_base, arcpath), path=node.path)
+                assert node.arcpath is not None, f"{node=}"
+                added_files[node.arcpath] = node
+            elif node.symtarget is not None:
+                remaining_symlinks.add(node)
+            elif node.directory:
+                pass
+            else:
+                raise ValueError(f"Invalid Archive Node: {repr(node)}")
+
+        assert None not in added_files
+
+        # Resolve symlinks in second pass: zipfile does not support symlinks, so add files to zip archive
+        while True:
+            if not remaining_symlinks:
+                break
+            symlinks_this_time = set()
+            extra_added_files = {}
+            for symlink in remaining_symlinks:
+                symlink_files_for_zip = {}
+                symlink_target_path = calculate_symlink_target(symlink)
+                if symlink_target_path in added_files:
+                    symlink_files_for_zip[symlink.arcpath] = added_files[symlink_target_path]
+                else:
+                    symlink_target_path_slash = symlink_target_path + "/"
+                    for added_file in added_files:
+                        if added_file.startswith(symlink_target_path_slash):
+                            path_in_symlink = symlink.arcpath + "/" + added_file.removeprefix(symlink_target_path_slash)
+                            symlink_files_for_zip[path_in_symlink] = added_files[added_file]
+                if symlink_files_for_zip:
+                    symlinks_this_time.add(symlink)
+                    extra_added_files.update(symlink_files_for_zip)
+                    files_for_zip = [{"arcpath": f"{archive_base}/{sym_path}", "data": sym_info.data, "mode": sym_info.mode} for sym_path, sym_info in symlink_files_for_zip.items()]
+                    archiver.add_symlink(arcpath=f"{archive_base}/{symlink.arcpath}", target=symlink.symtarget, time=symlink.time, files_for_zip=files_for_zip)
+            # if not symlinks_this_time:
+            #     logger.info("files added: %r", set(path for path in added_files.keys()))
+            assert symlinks_this_time, f"No targets found for symlinks: {remaining_symlinks}"
+            remaining_symlinks.difference_update(symlinks_this_time)
+            added_files.update(extra_added_files)
+
+    def add_directory_tree(self, arc_dir: str, path: Path, time: datetime.datetime):
+        assert path.is_dir()
+        for files_dir, _, filenames in os.walk(path):
+            files_dir_path = Path(files_dir)
+            rel_files_path = files_dir_path.relative_to(path)
+            for filename in filenames:
+                self.add_file(NodeInArchive.from_fs(arcpath=arc_join(arc_dir, str(rel_files_path), filename), path=files_dir_path / filename, time=time))
+
+    def _add_files_recursively(self, arc_dir: str, paths: list[Path], time: datetime.datetime):
+        logger.debug(f"_add_files_recursively({arc_dir=} {paths=})")
+        for path in paths:
+            arcpath = arc_join(arc_dir, path.name)
+            if path.is_file():
+                logger.debug("Adding %s as %s", path, arcpath)
+                self.add_file(NodeInArchive.from_fs(arcpath=arcpath, path=path, time=time))
+            elif path.is_dir():
+                self._add_files_recursively(arc_dir=arc_join(arc_dir, path.name), paths=list(path.iterdir()), time=time)
+            else:
+                raise ValueError(f"Unsupported file type to add recursively: {path}")
+
+    def add_file_mapping(self, arc_dir: str, file_mapping: dict[str, list[str]], file_mapping_root: Path, context: dict[str, str], time: datetime.datetime):
+        for meta_rel_destdir, meta_file_globs in file_mapping.items():
+            rel_destdir = configure_text(meta_rel_destdir, context=context)
+            assert "@" not in rel_destdir, f"archive destination should not contain an @ after configuration ({repr(meta_rel_destdir)}->{repr(rel_destdir)})"
+            for meta_file_glob in meta_file_globs:
+                file_glob = configure_text(meta_file_glob, context=context)
+                assert "@" not in rel_destdir, f"archive glob should not contain an @ after configuration ({repr(meta_file_glob)}->{repr(file_glob)})"
+                if ":" in file_glob:
+                    original_path, new_filename = file_glob.rsplit(":", 1)
+                    assert ":" not in original_path, f"Too many ':' in {repr(file_glob)}"
+                    assert "/" not in new_filename, f"New filename cannot contain a '/' in {repr(file_glob)}"
+                    path = file_mapping_root / original_path
+                    arcpath = arc_join(arc_dir, rel_destdir, new_filename)
+                    if path.suffix == ".in":
+                        data = configure_file(path, context=context)
+                        logger.debug("Adding processed %s -> %s", path, arcpath)
+                        self.add_file(NodeInArchive.from_data(arcpath=arcpath, data=data, time=time))
+                    else:
+                        logger.debug("Adding %s -> %s", path, arcpath)
+                        self.add_file(NodeInArchive.from_fs(arcpath=arcpath, path=path, time=time))
+                else:
+                    relative_file_paths = glob.glob(file_glob, root_dir=file_mapping_root)
+                    assert relative_file_paths, f"Glob '{file_glob}' does not match any file"
+                    self._add_files_recursively(arc_dir=arc_join(arc_dir, rel_destdir), paths=[file_mapping_root / p for p in relative_file_paths], time=time)
+
+
+class SourceCollector:
+    # TreeItem = collections.namedtuple("TreeItem", ("path", "mode", "data", "symtarget", "directory", "time"))
+    def __init__(self, root: Path, commit: str, filter: typing.Optional[Callable[[str], bool]], executer: Executer):
+        self.root = root
+        self.commit = commit
+        self.filter = filter
+        self.executer = executer
+
+    def get_archive_file_tree(self) -> ArchiveFileTree:
+        git_archive_args = ["git", "archive", "--format=tar.gz", self.commit, "-o", "/dev/stdout"]
+        logger.info("Executing args=%r", git_archive_args)
+        contents_tgz = subprocess.check_output(git_archive_args, cwd=self.root, text=False)
+        tar_archive = tarfile.open(fileobj=io.BytesIO(contents_tgz), mode="r:gz")
+        filenames = tuple(m.name for m in tar_archive if (m.isfile() or m.issym()))
+
+        file_times = self._get_file_times(paths=filenames)
+        git_contents = ArchiveFileTree()
+        for ti in tar_archive:
+            if self.filter and not self.filter(ti.name):
+                continue
+            data = None
+            symtarget = None
+            directory = False
+            file_time = None
+            if ti.isfile():
+                contents_file = tar_archive.extractfile(ti.name)
+                data = contents_file.read()
+                file_time = file_times[ti.name]
+            elif ti.issym():
+                symtarget = ti.linkname
+                file_time = file_times[ti.name]
+            elif ti.isdir():
+                directory = True
+            else:
+                raise ValueError(f"{ti.name}: unknown type")
+            node = NodeInArchive(arcpath=ti.name, data=data, mode=ti.mode, symtarget=symtarget, time=file_time, directory=directory)
+            git_contents.add_file(node)
+        return git_contents
+
+    def _get_file_times(self, paths: tuple[str, ...]) -> dict[str, datetime.datetime]:
+        dry_out = textwrap.dedent("""\
+            time=2024-03-14T15:40:25-07:00
+
+            M\tCMakeLists.txt
+        """)
+        git_log_out = self.executer.check_output(["git", "log", "--name-status", '--pretty=time=%cI', self.commit], dry_out=dry_out, cwd=self.root).splitlines(keepends=False)
+        current_time = None
+        set_paths = set(paths)
+        path_times: dict[str, datetime.datetime] = {}
+        for line in git_log_out:
+            if not line:
+                continue
+            if line.startswith("time="):
+                current_time = safe_isotime_to_datetime(line.removeprefix("time="))
+                continue
+            mod_type, file_paths = line.split(maxsplit=1)
+            assert current_time is not None
+            for file_path in file_paths.split("\t"):
+                if file_path in set_paths and file_path not in path_times:
+                    path_times[file_path] = current_time
+
+        # FIXME: find out why some files are not shown in "git log"
+        # assert set(path_times.keys()) == set_paths
+        if set(path_times.keys()) != set_paths:
+            found_times = set(path_times.keys())
+            paths_without_times = set_paths.difference(found_times)
+            logger.warning("No times found for these paths: %s", paths_without_times)
+            max_time = max(time for time in path_times.values())
+            for path in paths_without_times:
+                path_times[path] = max_time
+
+        return path_times
+
+
+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):
+        self.release_info = release_info
+        self.project = release_info["name"]
+        self.version = self.extract_sdl_version(root=root, release_info=release_info)
+        self.root = root
+        self.commit = commit
+        self.revision = revision
+        self.dist_path = dist_path
+        self.section_printer = section_printer
+        self.executer = executer
+        self.cmake_generator = cmake_generator
+        self.cpu_count = multiprocessing.cpu_count()
+        self.deps_path = deps_path
+        self.overwrite = overwrite
+        self.github = github
+        self.fast = fast
+        self.arc_time = datetime.datetime.now()
+
+        self.artifacts: dict[str, Path] = {}
+
+    def get_context(self, extra_context: typing.Optional[dict[str, str]]=None) -> dict[str, str]:
+        ctx = {
+            "PROJECT_NAME": self.project,
+            "PROJECT_VERSION": self.version,
+            "PROJECT_COMMIT": self.commit,
+            "PROJECT_REVISION": self.revision,
+            "PROJECT_ROOT": str(self.root),
+        }
+        if extra_context:
+            ctx.update(extra_context)
+        return ctx
+
+    @property
+    def dry(self) -> bool:
+        return self.executer.dry
+
+    def prepare(self):
+        logger.debug("Creating dist folder")
+        self.dist_path.mkdir(parents=True, exist_ok=True)
+
+    @classmethod
+    def _path_filter(cls, path: str) -> bool:
+        if ".gitmodules" in path:
+            return True
+        if path.startswith(".git"):
+            return False
+        return True
+
+    @classmethod
+    def _external_repo_path_filter(cls, path: str) -> bool:
+        if not cls._path_filter(path):
+            return False
+        if path.startswith("test/") or path.startswith("tests/"):
+            return False
+        return True
+
+    def create_source_archives(self) -> None:
+        source_collector = SourceCollector(root=self.root, commit=self.commit, executer=self.executer, filter=self._path_filter)
+        print(f"Collecting sources of {self.project}...")
+        archive_tree = source_collector.get_archive_file_tree()
+        latest_mod_time = archive_tree.get_latest_mod_time()
+        archive_tree.add_file(NodeInArchive.from_text(arcpath=REVISION_TXT, text=f"{self.revision}\n", time=latest_mod_time))
+        archive_tree.add_file(NodeInArchive.from_text(arcpath=f"{GIT_HASH_FILENAME}", text=f"{self.commit}\n", time=latest_mod_time))
+        archive_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["source"].get("files", {}), file_mapping_root=self.root, context=self.get_context(), time=latest_mod_time)
+
+        archive_base = f"{self.project}-{self.version}"
+        zip_path = self.dist_path / f"{archive_base}.zip"
+        tgz_path = self.dist_path / f"{archive_base}.tar.gz"
+        txz_path = self.dist_path / f"{archive_base}.tar.xz"
+
+        logger.info("Creating zip/tgz/txz source archives ...")
+        if self.dry:
+            zip_path.touch()
+            tgz_path.touch()
+            txz_path.touch()
+        else:
+            with Archiver(zip_path=zip_path, tgz_path=tgz_path, txz_path=txz_path) as archiver:
+                print(f"Adding source files of {self.project}...")
+                archive_tree.add_to_archiver(archive_base=archive_base, archiver=archiver)
+
+                for extra_repo in self.release_info["source"].get("extra-repos", []):
+                    extra_repo_root = self.root / extra_repo
+                    assert (extra_repo_root / ".git").exists(), f"{extra_repo_root} must be a git repo"
+                    extra_repo_commit = self.executer.check_output(["git", "rev-parse", "HEAD"], dry_out=f"gitsha-extra-repo-{extra_repo}", cwd=extra_repo_root).strip()
+                    extra_repo_source_collector = SourceCollector(root=extra_repo_root, commit=extra_repo_commit, executer=self.executer, filter=self._external_repo_path_filter)
+                    print(f"Collecting sources of {extra_repo} ...")
+                    extra_repo_archive_tree = extra_repo_source_collector.get_archive_file_tree()
+                    print(f"Adding source files of {extra_repo} ...")
+                    extra_repo_archive_tree.add_to_archiver(archive_base=f"{archive_base}/{extra_repo}", archiver=archiver)
+
+            for file in self.release_info["source"]["checks"]:
+                assert f"{archive_base}/{file}" in archiver.added_files, f"'{archive_base}/{file}' must exist"
+
+        logger.info("... done")
+
+        self.artifacts["src-zip"] = zip_path
+        self.artifacts["src-tar-gz"] = tgz_path
+        self.artifacts["src-tar-xz"] = txz_path
+
+        if not self.dry:
+            with tgz_path.open("r+b") as f:
+                # Zero the embedded timestamp in the gzip'ed tarball
+                f.seek(4, 0)
+                f.write(b"\x00\x00\x00\x00")
+
+    def create_dmg(self, configuration: str="Release") -> None:
+        dmg_in = self.root / self.release_info["dmg"]["path"]
+        xcode_project = self.root / self.release_info["dmg"]["project"]
+        assert xcode_project.is_dir(), f"{xcode_project} must be a directory"
+        assert (xcode_project / "project.pbxproj").is_file, f"{xcode_project} must contain project.pbxproj"
+        if not self.fast:
+            dmg_in.unlink(missing_ok=True)
+        build_xcconfig = self.release_info["dmg"].get("build-xcconfig")
+        if build_xcconfig:
+            shutil.copy(self.root / build_xcconfig, xcode_project.parent / "build.xcconfig")
+
+        xcode_scheme = self.release_info["dmg"].get("scheme")
+        xcode_target = self.release_info["dmg"].get("target")
+        assert xcode_scheme or xcode_target, "dmg needs scheme or target"
+        assert not (xcode_scheme and xcode_target), "dmg cannot have both scheme and target set"
+        if xcode_scheme:
+            scheme_or_target = "-scheme"
+            target_like = xcode_scheme
+        else:
+            scheme_or_target = "-target"
+            target_like = xcode_target
+        self.executer.run(["xcodebuild", "ONLY_ACTIVE_ARCH=NO", "-project", xcode_project, scheme_or_target, target_like, "-configuration", configuration])
+        if self.dry:
+            dmg_in.parent.mkdir(parents=True, exist_ok=True)
+            dmg_in.touch()
+
+        assert dmg_in.is_file(), f"{self.project}.dmg was not created by xcodebuild"
+
+        dmg_out = self.dist_path / f"{self.project}-{self.version}.dmg"
+        shutil.copy(dmg_in, dmg_out)
+        self.artifacts["dmg"] = dmg_out
+
+    @property
+    def git_hash_data(self) -> bytes:
+        return f"{self.commit}\n".encode()
+
+    def create_mingw_archives(self) -> None:
+        build_type = "Release"
+        build_parent_dir = self.root / "build-mingw"
+        ARCH_TO_GNU_ARCH = {
+            # "arm64": "aarch64",
+            "x86": "i686",
+            "x64": "x86_64",
+        }
+        ARCH_TO_TRIPLET = {
+            # "arm64": "aarch64-w64-mingw32",
+            "x86": "i686-w64-mingw32",
+            "x64": "x86_64-w64-mingw32",
+        }
+
+        new_env = dict(os.environ)
+
+        cmake_prefix_paths = []
+        mingw_deps_path = self.deps_path / "mingw-deps"
+
+        if "dependencies" in self.release_info["mingw"]:
+            shutil.rmtree(mingw_deps_path, ignore_errors=True)
+            mingw_deps_path.mkdir()
+
+            for triplet in ARCH_TO_TRIPLET.values():
+                (mingw_deps_path / triplet).mkdir()
+
+            def extract_filter(member: tarfile.TarInfo, path: str, /):
+                if member.name.startswith("SDL"):
+                    member.name = "/".join(Path(member.name).parts[1:])
+                return member
+            for dep in self.release_info.get("dependencies", {}):
+                extract_path = mingw_deps_path / f"extract-{dep}"
+                extract_path.mkdir()
+                with chdir(extract_path):
+                    tar_path = self.deps_path / glob.glob(self.release_info["mingw"]["dependencies"][dep]["artifact"], root_dir=self.deps_path)[0]
+                    logger.info("Extracting %s to %s", tar_path, mingw_deps_path)
+                    assert tar_path.suffix in (".gz", ".xz")
+                    with tarfile.open(tar_path, mode=f"r:{tar_path.suffix.strip('.')}") as tarf:
+                        tarf.extractall(filter=extract_filter)
+                    for arch, triplet in ARCH_TO_TRIPLET.items():
+                        install_cmd = self.release_info["mingw"]["dependencies"][dep]["install-command"]
+                        extra_configure_data = {
+                            "ARCH": ARCH_TO_GNU_ARCH[arch],
+                            "TRIPLET": triplet,
+                            "PREFIX": str(mingw_deps_path / triplet),
+                        }
+                        install_cmd = configure_text(install_cmd, context=self.get_context(extra_configure_data))
+                        self.executer.run(shlex.split(install_cmd), cwd=str(extract_path))
+
+            dep_binpath = mingw_deps_path / triplet / "bin"
+            assert dep_binpath.is_dir(), f"{dep_binpath} for PATH should exist"
+            dep_pkgconfig = mingw_deps_path / triplet / "lib/pkgconfig"
+            assert dep_pkgconfig.is_dir(), f"{dep_pkgconfig} for PKG_CONFIG_PATH should exist"
+
+            new_env["PATH"] = os.pathsep.join([str(dep_binpath), new_env["PATH"]])
+            new_env["PKG_CONFIG_PATH"] = str(dep_pkgconfig)
+            cmake_prefix_paths.append(mingw_deps_path)
+
+        new_env["CFLAGS"] = f"-O2 -ffile-prefix-map={self.root}=/src/{self.project}"
+        new_env["CXXFLAGS"] = f"-O2 -ffile-prefix-map={self.root}=/src/{self.project}"
+
+        assert any(system in self.release_info["mingw"] for system in ("autotools", "cmake"))
+        assert not all(system in self.release_info["mingw"] for system in ("autotools", "cmake"))
+
+        mingw_archs = set()
+        arc_root = f"{self.project}-{self.version}"
+        archive_file_tree = ArchiveFileTree()
+
+        if "autotools" in self.release_info["mingw"]:
+            for arch in self.release_info["mingw"]["autotools"]["archs"]:
+                triplet = ARCH_TO_TRIPLET[arch]
+                new_env["CC"] = f"{triplet}-gcc"
+                new_env["CXX"] = f"{triplet}-g++"
+                new_env["RC"] = f"{triplet}-windres"
+
+                assert arch not in mingw_archs
+                mingw_archs.add(arch)
+
+                build_path = build_parent_dir / f"build-{triplet}"
+                install_path = build_parent_dir / f"install-{triplet}"
+                shutil.rmtree(install_path, ignore_errors=True)
+                build_path.mkdir(parents=True, exist_ok=True)
+                context = self.get_context({
+                    "ARCH": arch,
+                    "DEP_PREFIX": str(mingw_deps_path / triplet),
+                })
+                extra_args = configure_text_list(text_list=self.release_info["mingw"]["autotools"]["args"], context=context)
+
+                with self.section_printer.group(f"Configuring MinGW {triplet} (autotools)"):
+                    assert "@" not in " ".join(extra_args), f"@ should not be present in extra arguments ({extra_args})"
+                    self.executer.run([
+                        self.root / "configure",
+                        f"--prefix={install_path}",
+                        f"--includedir=${{prefix}}/include",
+                        f"--libdir=${{prefix}}/lib",
+                        f"--bindir=${{prefix}}/bin",
+                        f"--exec-prefix=${{prefix}}/bin",
+                        f"--host={triplet}",
+                        f"--build=x86_64-none-linux-gnu",
+                        "CFLAGS=-O2",
+                        "CXXFLAGS=-O2",
+                        "LDFLAGS=-Wl,-s",
+                    ] + extra_args, cwd=build_path, env=new_env)
+                with self.section_printer.group(f"Build MinGW {triplet} (autotools)"):
+                    self.executer.run(["make", "V=1", f"-j{self.cpu_count}"], cwd=build_path, env=new_env)
+                with self.section_printer.group(f"Install MinGW {triplet} (autotools)"):
+                    self.executer.run(["make", "install"], cwd=build_path, env=new_env)
+                archive_file_tree.add_directory_tree(arc_dir=arc_join(arc_root, triplet), path=install_path, time=self.arc_time)
+
+                print("Recording arch-dependent extra files for MinGW development archive ...")
+                extra_context = {
+                    "TRIPLET": ARCH_TO_TRIPLET[arch],
+                }
+                archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["mingw"]["autotools"].get("files", {}), file_mapping_root=self.root, context=self.get_context(extra_context=extra_context), time=self.arc_time)
+
+        if "cmake" in self.release_info["mingw"]:
+            assert self.release_info["mingw"]["cmake"]["shared-static"] in ("args", "both")
+            for arch in self.release_info["mingw"]["cmake"]["archs"]:
+                triplet = ARCH_TO_TRIPLET[arch]
+                new_env["CC"] = f"{triplet}-gcc"
+                new_env["CXX"] = f"{triplet}-g++"
+                new_env["RC"] = f"{triplet}-windres"
+
+                assert arch not in mingw_archs
+                mingw_archs.add(arch)
+
+                context = self.get_context({
+                    "ARCH": arch,
+                    "DEP_PREFIX": str(mingw_deps_path / triplet),
+                })
+                extra_args = configure_text_list(text_list=self.release_info["mingw"]["cmake"]["args"], context=context)
+
+                build_path = build_parent_dir / f"build-{triplet}"
+                install_path = build_parent_dir / f"install-{triplet}"
+                shutil.rmtree(install_path, ignore_errors=True)
+                build_path.mkdir(parents=True, exist_ok=True)
+                if self.release_info["mingw"]["cmake"]["shared-static"] == "args":
+                    args_for_shared_static = ([], )
+                elif self.release_info["mingw"]["cmake"]["shared-static"] == "both":
+                    args_for_shared_static = (["-DBUILD_SHARED_LIBS=ON"], ["-DBUILD_SHARED_LIBS=OFF"])
+                for arg_for_shared_static in args_for_shared_static:
+                    with self.section_printer.group(f"Configuring MinGW {triplet} (CMake)"):
+                        assert "@" not in " ".join(extra_args), f"@ should not be present in extra arguments ({extra_args})"
+                        self.executer.run([
+                            f"cmake",
+                            f"-S", str(self.root), "-B", str(build_path),
+                            f"-DCMAKE_BUILD_TYPE={build_type}",
+                            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_PREFIX_PATH={mingw_deps_path / triplet}",
+                            f"-DCMAKE_INSTALL_PREFIX={install_path}",
+                            f"-DCMAKE_INSTALL_INCLUDEDIR=include",
+                            f"-DCMAKE_INSTALL_LIBDIR=lib",
+                            f"-DCMAKE_INSTALL_BINDIR=bin",
+                            f"-DCMAKE_INSTALL_DATAROOTDIR=share",
+                            f"-DCMAKE_TOOLCHAIN_FILE={self.root}/build-scripts/cmake-toolchain-mingw64-{ARCH_TO_GNU_ARCH[arch]}.cmake",
+                            f"-G{self.cmake_generator}",
+                        ] + extra_args + ([] if self.fast else ["--fresh"]) + arg_for_shared_static, cwd=build_path, env=new_env)
+                    with self.section_printer.group(f"Build MinGW {triplet} (CMake)"):
+                        self.executer.run(["cmake", "--build", str(build_path), "--verbose", "--config", build_type], cwd=build_path, env=new_env)
+                    with self.section_printer.group(f"Install MinGW {triplet} (CMake)"):
+                        self.executer.run(["cmake", "--install", str(build_path)], cwd=build_path, env=new_env)
+                archive_file_tree.add_directory_tree(arc_dir=arc_join(arc_root, triplet), path=install_path, time=self.arc_time)
+
+                print("Recording arch-dependent extra files for MinGW development archive ...")
+                extra_context = {
+                    "TRIPLET": ARCH_TO_TRIPLET[arch],
+                }
+                archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["mingw"]["cmake"].get("files", {}), file_mapping_root=self.root, context=self.get_context(extra_context=extra_context), time=self.arc_time)
+                print("... done")
+
+        print("Recording extra files for MinGW development archive ...")
+        archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["mingw"].get("files", {}), file_mapping_root=self.root, context=self.get_context(), time=self.arc_time)
+        print("... done")
+
+        print("Creating zip/tgz/txz development archives ...")
+        zip_path = self.dist_path / f"{self.project}-devel-{self.version}-mingw.zip"
+        tgz_path = self.dist_path / f"{self.project}-devel-{self.version}-mingw.tar.gz"
+        txz_path = self.dist_path / f"{self.project}-devel-{self.version}-mingw.tar.xz"
+
+        with Archiver(zip_path=zip_path, tgz_path=tgz_path, txz_path=txz_path) as archiver:
+            archive_file_tree.add_to_archiver(archive_base="", archiver=archiver)
+            archiver.add_git_hash(arcdir=arc_root, commit=self.commit, time=self.arc_time)
+        print("... done")
+
+        self.artifacts["mingw-devel-zip"] = zip_path
+        self.artifacts["mingw-devel-tar-gz"] = tgz_path
+        self.artifacts["mingw-devel-tar-xz"] = txz_path
+
+    def _detect_android_api(self, android_home: str) -> typing.Optional[int]:
+        platform_dirs = list(Path(p) for p in glob.glob(f"{android_home}/platforms/android-*"))
+        re_platform = re.compile("android-([0-9]+)")
+        platform_versions = []
+        for platform_dir in platform_dirs:
+            logger.debug("Found Android Platform SDK: %s", platform_dir)
+            if m:= re_platform.match(platform_dir.name):
+                platform_versions.append(int(m.group(1)))
+        platform_versions.sort()
+        logger.info("Available platform versions: %s", platform_versions)
+        platform_versions = list(filter(lambda v: v >= self._android_api_minimum, platform_versions))
+        logger.info("Valid platform versions (>=%d): %s", self._android_api_minimum, platform_versions)
+        if not platform_versions:
+            return None
+        android_api = platform_versions[0]
+        logger.info("Selected API version %d", android_api)
+        return android_api
+
+    def _get_prefab_json_text(self) -> str:
+        return textwrap.dedent(f"""\
+            {{
+                "schema_version": 2,
+                "name": "{self.project}",
+                "version": "{self.version}",
+                "dependencies": []
+            }}
+        """)
+
+    def _get_prefab_module_json_text(self, library_name: typing.Optional[str], export_libraries: list[str]) -> str:
+        for lib in export_libraries:
+            assert isinstance(lib, str), f"{lib} must be a string"
+        module_json_dict = {
+            "export_libraries": export_libraries,
+        }
+        if library_name:
+            module_json_dict["library_name"] = f"lib{library_name}"
+        return json.dumps(module_json_dict, indent=4)
+
+    @property
+    def _android_api_minimum(self):
+        return self.release_info["android"]["api-minimum"]
+
+    @property
+    def _android_api_target(self):
+        return self.release_info["android"]["api-target"]
+
+    @property
+    def _android_ndk_minimum(self):
+        return self.release_info["android"]["ndk-minimum"]
+
+    def _get_prefab_abi_json_text(self, abi: str, cpp: bool, shared: bool) -> str:
+        abi_json_dict = {
+            "abi": abi,
+            "api": self._android_api_minimum,
+            "ndk": self._android_ndk_minimum,
+            "stl": "c++_shared" if cpp else "none",
+            "static": not shared,
+        }
+        return json.dumps(abi_json_dict, indent=4)
+
+    def _get_android_manifest_text(self) -> str:
+        return textwrap.dedent(f"""\
+            <manifest
+                xmlns:android="http://schemas.android.com/apk/res/android"
+                package="org.libsdl.android.{self.project}" android:versionCode="1"
+                android:versionName="1.0">
+                <uses-sdk android:minSdkVersion="{self._android_api_minimum}"
+                          android:targetSdkVersion="{self._android_api_target}" />
+            </manifest>
+        """)
+
+    def create_android_archives(self, android_api: int, android_home: Path, android_ndk_home: Path) -> None:
+        cmake_toolchain_file = Path(android_ndk_home) / "build/cmake/android.toolchain.cmake"
+        if not cmake_toolchain_file.exists():
+            logger.error("CMake toolchain file does not exist (%s)", cmake_toolchain_file)
+            raise SystemExit(1)
+        aar_path =  self.dist_path / f"{self.project}-{self.version}.aar"
+        android_abis = self.release_info["android"]["abis"]
+        java_jars_added = False
+        module_data_added = False
+        android_deps_path = self.deps_path / "android-deps"
+        shutil.rmtree(android_deps_path, ignore_errors=True)
+
+        for dep, depinfo in self.release_info["android"].get("dependencies", {}).items():
+            android_aar = self.deps_path / glob.glob(depinfo["artifact"], root_dir=self.deps_path)[0]
+            with self.section_printer.group(f"Extracting Android dependency {dep} ({android_aar.name})"):
+                self.executer.run([sys.executable, str(android_aar), "-o", str(android_deps_path)])
+
+        for module_name, module_info in self.release_info["android"]["modules"].items():
+            assert "type" in module_info and module_info["type"] in ("interface", "library"), f"module {module_name} must have a valid type"
+
+        archive_file_tree = ArchiveFileTree()
+
+        for android_abi in android_abis:
+            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"
+                shutil.rmtree(install_dir, ignore_errors=True)
+                assert not install_dir.is_dir(), f"{install_dir} should not exist prior to build"
+                build_type = "Release"
+                cmake_args = [
+                    "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}"''',
+                    f"-DCMAKE_TOOLCHAIN_FILE={cmake_toolchain_file}",
+                    f"-DCMAKE_PREFIX_PATH={str(android_deps_path)}",
+                    f"-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH",
+                    f"-DANDROID_HOME={android_home}",
+                    f"-DANDROID_PLATFORM={android_api}",
+                    f"-DANDROID_ABI={android_abi}",
+                    "-DCMAKE_POSITION_INDEPENDENT_CODE=ON",
+                    f"-DCMAKE_INSTALL_PREFIX={install_dir}",
+                    "-DCMAKE_INSTALL_INCLUDEDIR=include ",
+                    "-DCMAKE_INSTALL_LIBDIR=lib",
+                    "-DCMAKE_INSTALL_DATAROOTDIR=share",
+                    f"-DCMAKE_BUILD_TYPE={build_type}",
+                    f"-G{self.cmake_generator}",
+                ] + self.release_info["android"]["cmake"]["args"] + ([] if self.fast else ["--fresh"])
+                build_args = [
+                    "cmake",
+                    "--build", str(build_dir),
+                    "--verbose",
+                    "--config", build_type,
+                ]
+                install_args = [
+                    "cmake",
+                    "--install", str(build_dir),
+                    "--config", build_type,
+                ]
+                self.executer.run(cmake_args)
+                self.executer.run(build_args)
+                self.executer.run(install_args)
+
+                for module_name, module_info in self.release_info["android"]["modules"].items():
+                    arcdir_prefab_module = f"prefab/modules/{module_name}"
+                    if module_info["type"] == "library":
+                        library = install_dir / module_info["library"]
+                        assert library.suffix in (".so", ".a")
+                        assert library.is_file(), f"CMake should have built library '{library}' for module {module_name}"
+                        arcdir_prefab_libs = f"{arcdir_prefab_module}/libs/android.{android_abi}"
+                        archive_file_tree.add_file(NodeInArchive.from_fs(arcpath=f"{arcdir_prefab_libs}/{library.name}", path=library, time=self.arc_time))
+                        archive_file_tree.add_file(NodeInArchive.from_text(arcpath=f"{arcdir_prefab_libs}/abi.json", text=self._get_prefab_abi_json_text(abi=android_abi, cpp=False, shared=library.suffix == ".so"), time=self.arc_time))
+
+                    if not module_data_added:
+                        library_name = None
+                        if module_info["type"] == "library":
+                            library_name = Path(module_info["library"]).stem.removeprefix("lib")
+                        export_libraries = module_info.get("export-libraries", [])
+                        archive_file_tree.add_file(NodeInArchive.from_text(arcpath=arc_join(arcdir_prefab_module, "module.json"), text=self._get_prefab_module_json_text(library_name=library_name, export_libraries=export_libraries), time=self.arc_time))
+                        arcdir_prefab_include = f"prefab/modules/{module_name}/include"
+                        if "includes" in module_info:
+                            archive_file_tree.add_file_mapping(arc_dir=arcdir_prefab_include, file_mapping=module_info["includes"], file_mapping_root=install_dir, context=self.get_context(), time=self.arc_time)
+                        else:
+                            archive_file_tree.add_file(NodeInArchive.from_text(arcpath=arc_join(arcdir_prefab_include, ".keep"), text="\n", time=self.arc_time))
+                module_data_added = True
+
+                if not java_jars_added:
+                    java_jars_added = True
+                    if "jars" in self.release_info["android"]:
+                        classes_jar_path = install_dir / configure_text(text=self.release_info["android"]["jars"]["classes"], context=self.get_context())
+                        sources_jar_path = install_dir / configure_text(text=self.release_info["android"]["jars"]["sources"], context=self.get_context())
+                        doc_jar_path = install_dir / configure_text(text=self.release_info["android"]["jars"]["doc"], context=self.get_context())
+                        assert classes_jar_path.is_file(), f"CMake should have compiled the java sources and archived them into a JAR ({classes_jar_path})"
+                        assert sources_jar_path.is_file(), f"CMake should have archived the java sources into a JAR ({sources_jar_path})"
+                        assert doc_jar_path.is_file(), f"CMake should have archived javadoc into a JAR ({doc_jar_path})"
+
+                        archive_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes.jar", path=classes_jar_path, time=self.arc_time))
+                        archive_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes-sources.jar", path=sources_jar_path, time=self.arc_time))
+                        archive_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes-doc.jar", path=doc_jar_path, time=self.arc_time))
+
+        assert ("jars" in self.release_info["android"] and java_jars_added) or "jars" not in self.release_info["android"], "Must have archived java JAR archives"
+
+        archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["android"].get("files", {}), file_mapping_root=self.root, context=self.get_context(), time=self.arc_time)
+
+        archive_file_tree.add_file(NodeInArchive.from_text(arcpath="prefab/prefab.json", text=self._get_prefab_json_text(), time=self.arc_time))
+        archive_file_tree.add_file(NodeInArchive.from_text(arcpath="AndroidManifest.xml", text=self._get_android_manifest_text(), time=self.arc_time))
+
+        with Archiver(zip_path=aar_path) as archiver:
+            archive_file_tree.add_to_archiver(archive_base="", archiver=archiver)
+            archiver.add_git_hash(arcdir="", commit=self.commit, time=self.arc_time)
+        self.artifacts[f"android-aar"] = aar_path
+
+    def download_dependencies(self):
+        shutil.rmtree(self.deps_path, ignore_errors=True)
+        self.deps_path.mkdir(parents=True)
+
+        if self.github:
+            with open(os.environ["GITHUB_OUTPUT"], "a") as f:
+                f.write(f"dep-path={self.deps_path.absolute()}\n")
+
+        for dep, depinfo in self.release_info.get("dependencies", {}).items():
+            startswith = depinfo["startswith"]
+            dep_repo = depinfo["repo"]
+            # FIXME: dropped "--exclude-pre-releases"
+            dep_string_data = self.executer.check_output(["gh", "-R", dep_repo, "release", "list", "--exclude-drafts", "--json", "name,createdAt,tagName", "--jq", f'[.[]|select(.name|startswith("{startswith}"))]|max_by(.createdAt)']).strip()
+            dep_data = json.loads(dep_string_data)
+            dep_tag = dep_data["tagName"]
+            dep_version = dep_data["name"]
+            logger.info("Download dependency %s version %s (tag=%s) ", dep, dep_version, dep_tag)
+            self.executer.run(["gh", "-R", dep_repo, "release", "download", dep_tag], cwd=self.deps_path)
+            if self.github:
+                with open(os.environ["GITHUB_OUTPUT"], "a") as f:
+                    f.write(f"dep-{dep.lower()}-version={dep_version}\n")
+
+    def verify_dependencies(self):
+        for dep, depinfo in self.release_info.get("dependencies", {}).items():
+            if "mingw" in self.release_info:
+                mingw_matches = glob.glob(self.release_info["mingw"]["dependencies"][dep]["artifact"], root_dir=self.deps_path)
+                assert len(mingw_matches) == 1, f"Exactly one archive matches mingw {dep} dependency: {mingw_matches}"
+            if "dmg" in self.release_info:
+                dmg_matches = glob.glob(self.release_info["dmg"]["dependencies"][dep]["artifact"], root_dir=self.deps_path)
+                assert len(dmg_matches) == 1, f"Exactly one archive matches dmg {dep} dependency: {dmg_matches}"
+            if "msvc" in self.release_info:
+                msvc_matches = glob.glob(self.release_info["msvc"]["dependencies"][dep]["artifact"], root_dir=self.deps_path)
+                assert len(msvc_matches) == 1, f"Exactly one archive matches msvc {dep} dependency: {msvc_matches}"
+            if "android" in self.release_info:
+                android_matches = glob.glob(self.release_info["android"]["dependencies"][dep]["artifact"], root_dir=self.deps_path)
+                assert len(android_matches) == 1, f"Exactly one archive matches msvc {dep} dependency: {msvc_matches}"
+
+    @staticmethod
+    def _arch_to_vs_platform(arch: str, configuration: str="Release") -> VsArchPlatformConfig:
+        ARCH_TO_VS_PLATFORM = {
+            "x86": VsArchPlatformConfig(arch="x86", platform="Win32", configuration=configuration),
+            "x64": VsArchPlatformConfig(arch="x64", platform="x64", configuration=configuration),
+            "arm64": VsArchPlatformConfig(arch="arm64", platform="ARM64", configuration=configuration),
+        }
+        return ARCH_TO_VS_PLATFORM[arch]
+
+    def build_msvc(self):
+        with self.section_printer.group("Find Visual Studio"):
+            vs = VisualStudio(executer=self.executer)
+        for arch in self.release_info["msvc"].get("msbuild", {}).get("archs", []):
+            self._build_msvc_msbuild(arch_platform=self._arch_to_vs_platform(arch=arch), vs=vs)
+        if "cmake" in self.release_info["msvc"]:
+            deps_path = self.root / "msvc-deps"
+            shutil.rmtree(deps_path, ignore_errors=True)
+            dep_roots = []
+            for dep, depinfo in self.release_info["msvc"].get("dependencies", {}).items():
+                dep_extract_path = deps_path / f"extract-{dep}"
+                msvc_zip = self.deps_path / glob.glob(depinfo["artifact"], root_dir=self.deps_path)[0]
+                with zipfile.ZipFile(msvc_zip, "r") as zf:
+                    zf.extractall(dep_extract_path)
+                contents_msvc_zip = glob.glob(str(dep_extract_path / "*"))
+                assert len(contents_msvc_zip) == 1, f"There must be exactly one root item in the root directory of {dep}"
+                dep_roots.append(contents_msvc_zip[0])
+
+            for arch in self.release_info["msvc"].get("cmake", {}).get("archs", []):
+                self._build_msvc_cmake(arch_platform=self._arch_to_vs_platform(arch=arch), dep_roots=dep_roots)
+        with self.section_printer.group("Create SDL VC development zip"):
+            self._build_msvc_devel()
+
+    def _build_msvc_msbuild(self, arch_platform: VsArchPlatformConfig, vs: VisualStudio):
+        platform_context = self.get_context(arch_platform.extra_context())
+        for dep, depinfo in self.release_info["msvc"].get("dependencies", {}).items():
+            msvc_zip = self.deps_path / glob.glob(depinfo["artifact"], root_dir=self.deps_path)[0]
+
+            src_globs = [configure_text(instr["src"], context=platform_context) for instr in depinfo["copy"]]
+            with zipfile.ZipFile(msvc_zip, "r") as zf:
+                for member in zf.namelist():
+                    member_path = "/".join(Path(member).parts[1:])
+                    for src_i, src_glob in enumerate(src_globs):
+                        if fnmatch.fnmatch(member_path, src_glob):
+                            dst = (self.root / configure_text(depinfo["copy"][src_i]["dst"], context=platform_context)).resolve() / Path(member_path).name
+                            zip_data = zf.read(member)
+                            if dst.exists():
+                                identical = False
+                                if dst.is_file():
+                                    orig_bytes = dst.read_bytes()
+                                    if orig_bytes == zip_data:
+                                        identical = True
+                                if not identical:
+                                    logger.warning("Extracting dependency %s, will cause %s to be overwritten", dep, dst)
+                                    if not self.overwrite:
+                                        raise RuntimeError("Run with --overwrite to allow overwriting")
+                            logger.debug("Extracting %s -> %s", member, dst)
+
+                            dst.parent.mkdir(exist_ok=True, parents=True)
+                            dst.write_bytes(zip_data)
+
+        prebuilt_paths = set(self.root / full_prebuilt_path for prebuilt_path in self.release_info["msvc"]["msbuild"].get("prebuilt", []) for full_prebuilt_path in glob.glob(configure_text(prebuilt_path, context=platform_context), root_dir=self.root))
+        msbuild_paths = set(self.root / configure_text(f, context=platform_context) for file_mapping in (self.release_info["msvc"]["msbuild"]["files-lib"], self.release_info["msvc"]["msbuild"]["files-devel"]) for files_list in file_mapping.values() for f in files_list)
+        assert prebuilt_paths.issubset(msbuild_paths), f"msvc.msbuild.prebuilt must be a subset of (msvc.msbuild.files-lib, msvc.msbuild.files-devel)"
+        built_paths = msbuild_paths.difference(prebuilt_paths)
+        logger.info("MSbuild builds these files, to be included in the package: %s", built_paths)
+        if not self.fast:
+            for b in built_paths:
+                b.unlink(missing_ok=True)
+
+        rel_projects: list[str] = self.release_info["msvc"]["msbuild"]["projects"]
+        projects = list(self.root / p for p in rel_projects)
+
+        directory_build_props_src_relpath = self.release_info["msvc"]["msbuild"].get("directory-build-props")
+        for project in projects:
+            dir_b_props = project.parent / "Directory.Build.props"
+            dir_b_props.unlink(missing_ok = True)
+            if directory_build_props_src_relpath:
+                src = self.root / directory_build_props_src_relpath
+                logger.debug("Copying %s -> %s", src, dir_b_props)
+                shutil.copy(src=src, dst=dir_b_props)
+
+        with self.section_printer.group(f"Build {arch_platform.arch} VS binary"):
+            vs.build(arch_platform=arch_platform, projects=projects)
+
+        if self.dry:
+            for b in built_paths:
+                b.parent.mkdir(parents=True, exist_ok=True)
+                b.touch()
+
+        for b in built_paths:
+            assert b.is_file(), f"{b} has not been created"
+            b.parent.mkdir(parents=True, exist_ok=True)
+            b.touch()
+
+        zip_path = self.dist_path / f"{self.project}-{self.version}-win32-{arch_platform.arch}.zip"
+        zip_path.unlink(missing_ok=True)
+
+        logger.info("Collecting files...")
+        archive_file_tree = ArchiveFileTree()
+        archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["msbuild"]["files-lib"], file_mapping_root=self.root, context=platform_context, time=self.arc_time)
+        archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["files-lib"], file_mapping_root=self.root, context=platform_context, time=self.arc_time)
+
+        logger.info("Writing to %s", zip_path)
+        with Archiver(zip_path=zip_path) as archiver:
+            arc_root = f""
+            archive_file_tree.add_to_archiver(archive_base=arc_root, archiver=archiver)
+            archiver.add_git_hash(arcdir=arc_root, commit=self.commit, time=self.arc_time)
+        self.artifacts[f"VC-{arch_platform.arch}"] = zip_path
+
+        for p in built_paths:
+            assert p.is_file(), f"{p} should exist"
+
+    def _arch_platform_to_build_path(self, arch_platform: VsArchPlatformConfig) -> Path:
+        return self.root / f"build-vs-{arch_platform.arch}"
+
+    def _arch_platform_to_install_path(self, arch_platform: VsArchPlatformConfig) -> Path:
+        return self._arch_platform_to_build_path(arch_platform) / "prefix"
+
+    def _build_msvc_cmake(self, arch_platform: VsArchPlatformConfig, dep_roots: list[Path]):
+        build_path = self._arch_platform_to_build_path(arch_platform)
+        install_path = self._arch_platform_to_install_path(arch_platform)
+        platform_context = self.get_context(extra_context=arch_platform.extra_context())
+
+        build_type = "Release"
+
+        built_paths = set(install_path / configure_text(f, context=platform_context) for file_mapping in (self.release_info["msvc"]["cmake"]["files-lib"], self.release_info["msvc"]["cmake"]["files-devel"]) for files_list in file_mapping.values() for f in files_list)
+        logger.info("CMake builds these files, to be included in the package: %s", built_paths)
+        if not self.fast:
+            for b in built_paths:
+                b.unlink(missing_ok=True)
+
+        shutil.rmtree(install_path, ignore_errors=True)
+        build_path.mkdir(parents=True, exist_ok=True)
+        with self.section_printer.group(f"Configure VC CMake project for {arch_platform.arch}"):
+            self.executer.run([
+                "cmake", "-S", str(self.root), "-B", str(build_path),
+                "-A", arch_platform.platform,
+                "-DCMAKE_INSTALL_BINDIR=bin",
+                "-DCMAKE_INSTALL_DATAROOTDIR=share",
+                "-DCMAKE_INSTALL_INCLUDEDIR=include",
+                "-DCMAKE_INSTALL_LIBDIR=lib",
+                f"-DCMAKE_BUILD_TYPE={build_type}",
+                f"-DCMAKE_INSTALL_PREFIX={install_path}",
+                # MSVC debug information format flags are selected by an abstraction
+                "-DCMAKE_POLICY_DEFAULT_CMP0141=NEW",
+                # MSVC debug information format
+                "-DCMAKE_MSVC_DEBUG_INFORMATION_FORMAT=ProgramDatabase",
+                # Linker flags for executables
+                "-DCMAKE_EXE_LINKER_FLAGS=-INCREMENTAL:NO -DEBUG -OPT:REF -OPT:ICF",
+                # Linker flag for shared libraries
+                "-DCMAKE_SHARED_LINKER_FLAGS=-INCREMENTAL:NO -DEBUG -OPT:REF -OPT:ICF",
+                # MSVC runtime library flags are selected by an abstraction
+                "-DCMAKE_POLICY_DEFAULT_CMP0091=NEW",
+                # Use statically linked runtime (-MT) (ideally, should be "MultiThreaded$<$<CONFIG:Debug>:Debug>")
+                "-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded",
+                f"-DCMAKE_PREFIX_PATH={';'.join(str(s) for s in dep_roots)}",
+            ] + self.release_info["msvc"]["cmake"]["args"] + ([] if self.fast else ["--fresh"]))
+
+        with self.section_printer.group(f"Build VC CMake project for {arch_platform.arch}"):
+            self.executer.run(["cmake", "--build", str(build_path), "--verbose", "--config", build_type])
+        with self.section_printer.group(f"Install VC CMake project for {arch_platform.arch}"):
+            self.executer.run(["cmake", "--install", str(build_path), "--config", build_type])
+
+        if self.dry:
+            for b in built_paths:
+                b.parent.mkdir(parents=True, exist_ok=True)
+                b.touch()
+
+        zip_path = self.dist_path / f"{self.project}-{self.version}-win32-{arch_platform.arch}.zip"
+        zip_path.unlink(missing_ok=True)
+
+        logger.info("Collecting files...")
+        archive_file_tree = ArchiveFileTree()
+        archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["cmake"]["files-lib"], file_mapping_root=install_path, context=platform_context, time=self.arc_time)
+        archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["files-lib"], file_mapping_root=self.root, context=self.get_context(), time=self.arc_time)
+
+        logger.info("Creating %s", zip_path)
+        with Archiver(zip_path=zip_path) as archiver:
+            arc_root = f""
+            archive_file_tree.add_to_archiver(archive_base=arc_root, archiver=archiver)
+            archiver.add_git_hash(arcdir=arc_root, commit=self.commit, time=self.arc_time)
+
+        for p in built_paths:
+            assert p.is_file(), f"{p} should exist"
+
+    def _build_msvc_devel(self) -> None:
+        zip_path = self.dist_path / f"{self.project}-devel-{self.version}-VC.zip"
+        arc_root = f"{self.project}-{self.version}"
+
+        def copy_files_devel(ctx):
+            archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["msvc"]["files-devel"], file_mapping_root=self.root, context=ctx, time=self.arc_time)
+
+
+        logger.info("Collecting files...")
+        archive_file_tree = ArchiveFileTree()
+        if "msbuild" in self.release_info["msvc"]:
+            for arch in self.release_info["msvc"]["msbuild"]["archs"]:
+                arch_platform = self._arch_to_vs_platform(arch=arch)
+                platform_context = self.get_context(arch_platform.extra_context())
+                archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["msvc"]["msbuild"]["files-devel"], file_mapping_root=self.root, context=platform_context, time=self.arc_time)
+                copy_files_devel(ctx=platform_context)
+        if "cmake" in self.release_info["msvc"]:
+            for arch in self.release_info["msvc"]["cmake"]["archs"]:
+                arch_platform = self._arch_to_vs_platform(arch=arch)
+                platform_context = self.get_context(arch_platform.extra_context())
+                archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["msvc"]["cmake"]["files-devel"], file_mapping_root=self._arch_platform_to_install_path(arch_platform), context=platform_context, time=self.arc_time)
+                copy_files_devel(ctx=platform_context)
+
+        with Archiver(zip_path=zip_path) as archiver:
+            archive_file_tree.add_to_archiver(archive_base="", archiver=archiver)
+            archiver.add_git_hash(arcdir=arc_root, commit=self.commit, time=self.arc_time)
+        self.artifacts["VC-devel"] = zip_path
+
+    @classmethod
+    def extract_sdl_version(cls, root: Path, release_info: dict) -> str:
+        with open(root / release_info["version"]["file"], "r") as f:
+            text = f.read()
+        major = next(re.finditer(release_info["version"]["re_major"], text, flags=re.M)).group(1)
+        minor = next(re.finditer(release_info["version"]["re_minor"], text, flags=re.M)).group(1)
+        micro = next(re.finditer(release_info["version"]["re_micro"], text, flags=re.M)).group(1)
+        return f"{major}.{minor}.{micro}"
+
+
+def main(argv=None) -> int:
+    if sys.version_info < (3, 11):
+        logger.error("This script needs at least python 3.11")
+        return 1
+
+    parser = argparse.ArgumentParser(allow_abbrev=False, description="Create SDL release artifacts")
+    parser.add_argument("--root", metavar="DIR", type=Path, default=Path(__file__).absolute().parents[1], help="Root of project")
+    parser.add_argument("--release-info", metavar="JSON", dest="path_release_info", type=Path, default=Path(__file__).absolute().parent / "release-info.json", help="Path of release-info.json")
+    parser.add_argument("--dependency-folder", metavar="FOLDER", dest="deps_path", type=Path, default="deps", help="Directory containing pre-built archives of dependencies (will be removed when downloading archives)")
+    parser.add_argument("--out", "-o", metavar="DIR", dest="dist_path", type=Path, default="dist", help="Output directory")
+    parser.add_argument("--github", action="store_true", help="Script is running on a GitHub runner")
+    parser.add_argument("--commit", default="HEAD", help="Git commit/tag of which a release should be created")
+    parser.add_argument("--actions", choices=["download", "source", "android", "mingw", "msvc", "dmg"], required=True, nargs="+", dest="actions", help="What to do?")
+    parser.set_defaults(loglevel=logging.INFO)
+    parser.add_argument('--vs-year', dest="vs_year", help="Visual Studio year")
+    parser.add_argument('--android-api', type=int, dest="android_api", help="Android API version")
+    parser.add_argument('--android-home', dest="android_home", default=os.environ.get("ANDROID_HOME"), help="Android Home folder")
+    parser.add_argument('--android-ndk-home', dest="android_ndk_home", default=os.environ.get("ANDROID_NDK_HOME"), help="Android NDK Home folder")
+    parser.add_argument('--cmake-generator', dest="cmake_generator", default="Ninja", help="CMake Generator")
+    parser.add_argument('--debug', action='store_const', const=logging.DEBUG, dest="loglevel", help="Print script debug information")
+    parser.add_argument('--dry-run', action='store_true', dest="dry", help="Don't execute anything")
+    parser.add_argument('--force', action='store_true', dest="force", help="Ignore a non-clean git tree")
+    parser.add_argument('--overwrite', action='store_true', dest="overwrite", help="Allow potentially overwriting other projects")
+    parser.add_argument('--fast', action='store_true', dest="fast", help="Don't do a rebuild")
+
+    args = parser.parse_args(argv)
+    logging.basicConfig(level=args.loglevel, format='[%(levelname)s] %(message)s')
+    args.deps_path = args.deps_path.absolute()
+    args.dist_path = args.dist_path.absolute()
+    args.root = args.root.absolute()
+    args.dist_path = args.dist_path.absolute()
+    if args.dry:
+        args.dist_path = args.dist_path / "dry"
+
+    if args.github:
+        section_printer: SectionPrinter = GitHubSectionPrinter()
+    else:
+        section_printer = SectionPrinter()
+
+    if args.github and "GITHUB_OUTPUT" not in os.environ:
+        os.environ["GITHUB_OUTPUT"] = "/tmp/github_output.txt"
+
+    executer = Executer(root=args.root, dry=args.dry)
+
+    root_git_hash_path = args.root / GIT_HASH_FILENAME
+    root_is_maybe_archive = root_git_hash_path.is_file()
+    if root_is_maybe_archive:
+        logger.warning("%s detected: Building from archive", GIT_HASH_FILENAME)
+        archive_commit = root_git_hash_path.read_text().strip()
+        if args.commit != archive_commit:
+            logger.warning("Commit argument is %s, but archive commit is %s. Using %s.", args.commit, archive_commit, archive_commit)
+        args.commit = archive_commit
+        revision = (args.root / REVISION_TXT).read_text().strip()
+    else:
+        args.commit = executer.check_output(["git", "rev-parse", args.commit], dry_out="e5812a9fd2cda317b503325a702ba3c1c37861d9").strip()
+        revision = executer.check_output(["git", "describe", "--always", "--tags", "--long", args.commit], dry_out="preview-3.1.3-96-g9512f2144").strip()
+        logger.info("Using commit %s", args.commit)
+
+    try:
+        with args.path_release_info.open() as f:
+            release_info = json.load(f)
+    except FileNotFoundError:
+        logger.error(f"Could not find {args.path_release_info}")
+
+    releaser = Releaser(
+        release_info=release_info,
+        commit=args.commit,
+        revision=revision,
+        root=args.root,
+        dist_path=args.dist_path,
+        executer=executer,
+        section_printer=section_printer,
+        cmake_generator=args.cmake_generator,
+        deps_path=args.deps_path,
+        overwrite=args.overwrite,
+        github=args.github,
+        fast=args.fast,
+    )
+
+    if root_is_maybe_archive:
+        logger.warning("Building from archive. Skipping clean git tree check.")
+    else:
+        porcelain_status = executer.check_output(["git", "status", "--ignored", "--porcelain"], dry_out="\n").strip()
+        if porcelain_status:
+            print(porcelain_status)
+            logger.warning("The tree is dirty! Do not publish any generated artifacts!")
+            if not args.force:
+                raise Exception("The git repo contains modified and/or non-committed files. Run with --force to ignore.")
+
+    if args.fast:
+        logger.warning("Doing fast build! Do not publish generated artifacts!")
+
+    with section_printer.group("Arguments"):
+        print(f"project          = {releaser.project}")
+        print(f"version          = {releaser.version}")
+        print(f"revision         = {revision}")
+        print(f"commit           = {args.commit}")
+        print(f"out              = {args.dist_path}")
+        print(f"actions          = {args.actions}")
+        print(f"dry              = {args.dry}")
+        print(f"force            = {args.force}")
+        print(f"overwrite        = {args.overwrite}")
+        print(f"cmake_generator  = {args.cmake_generator}")
+
+    releaser.prepare()
+
+    if "download" in args.actions:
+        releaser.download_dependencies()
+
+    if set(args.actions).intersection({"msvc", "mingw", "android"}):
+        print("Verifying presence of dependencies (run 'download' action to download) ...")
+        releaser.verify_dependencies()
+        print("... done")
+
+    if "source" in args.actions:
+        if root_is_maybe_archive:
+            raise Exception("Cannot build source archive from source archive")
+        with section_printer.group("Create source archives"):
+            releaser.create_source_archives()
+
+    if "dmg" in args.actions:
+        if platform.system() != "Darwin" and not args.dry:
+            parser.error("framework artifact(s) can only be built on Darwin")
+
+        releaser.create_dmg()
+
+    if "msvc" in args.actions:
+        if platform.system() != "Windows" and not args.dry:
+            parser.error("msvc artifact(s) can only be built on Windows")
+        releaser.build_msvc()
+
+    if "mingw" in args.actions:
+        releaser.create_mingw_archives()
+
+    if "android" in args.actions:
+        if args.android_home is None or not Path(args.android_home).is_dir():
+            parser.error("Invalid $ANDROID_HOME or --android-home: must be a directory containing the Android SDK")
+        if args.android_ndk_home is None or not Path(args.android_ndk_home).is_dir():
+            parser.error("Invalid $ANDROID_NDK_HOME or --android_ndk_home: must be a directory containing the Android NDK")
+        if args.android_api is None:
+            with section_printer.group("Detect Android APIS"):
+                args.android_api = releaser._detect_android_api(android_home=args.android_home)
+        if args.android_api is None or not (Path(args.android_home) / f"platforms/android-{args.android_api}").is_dir():
+            parser.error("Invalid --android-api, and/or could not be detected")
+        with section_printer.group("Android arguments"):
+            print(f"android_home     = {args.android_home}")
+            print(f"android_ndk_home = {args.android_ndk_home}")
+            print(f"android_api      = {args.android_api}")
+        releaser.create_android_archives(
+            android_api=args.android_api,
+            android_home=args.android_home,
+            android_ndk_home=args.android_ndk_home,
+        )
+    with section_printer.group("Summary"):
+        print(f"artifacts = {releaser.artifacts}")
+
+    if args.github:
+        with open(os.environ["GITHUB_OUTPUT"], "a") as f:
+            f.write(f"project={releaser.project}\n")
+            f.write(f"version={releaser.version}\n")
+            for k, v in releaser.artifacts.items():
+                f.write(f"{k}={v.name}\n")
+    return 0
+
+
+if __name__ == "__main__":
+    raise SystemExit(main())

+ 18 - 0
Engine/lib/sdl/build-scripts/cmake-toolchain-mingw64-i686.cmake

@@ -0,0 +1,18 @@
+set(CMAKE_SYSTEM_NAME Windows)
+set(CMAKE_SYSTEM_PROCESSOR x86)
+
+find_program(CMAKE_C_COMPILER NAMES i686-w64-mingw32-gcc)
+find_program(CMAKE_CXX_COMPILER NAMES i686-w64-mingw32-g++)
+find_program(CMAKE_RC_COMPILER NAMES i686-w64-mingw32-windres windres)
+
+if(NOT CMAKE_C_COMPILER)
+	message(FATAL_ERROR "Failed to find CMAKE_C_COMPILER.")
+endif()
+
+if(NOT CMAKE_CXX_COMPILER)
+	message(FATAL_ERROR "Failed to find CMAKE_CXX_COMPILER.")
+endif()
+
+if(NOT CMAKE_RC_COMPILER)
+        message(FATAL_ERROR "Failed to find CMAKE_RC_COMPILER.")
+endif()

+ 18 - 0
Engine/lib/sdl/build-scripts/cmake-toolchain-mingw64-x86_64.cmake

@@ -0,0 +1,18 @@
+set(CMAKE_SYSTEM_NAME Windows)
+set(CMAKE_SYSTEM_PROCESSOR x86_64)
+
+find_program(CMAKE_C_COMPILER NAMES x86_64-w64-mingw32-gcc)
+find_program(CMAKE_CXX_COMPILER NAMES x86_64-w64-mingw32-g++)
+find_program(CMAKE_RC_COMPILER NAMES x86_64-w64-mingw32-windres windres)
+
+if(NOT CMAKE_C_COMPILER)
+	message(FATAL_ERROR "Failed to find CMAKE_C_COMPILER.")
+endif()
+
+if(NOT CMAKE_CXX_COMPILER)
+	message(FATAL_ERROR "Failed to find CMAKE_CXX_COMPILER.")
+endif()
+
+if(NOT CMAKE_RC_COMPILER)
+        message(FATAL_ERROR "Failed to find CMAKE_RC_COMPILER.")
+endif()

+ 14 - 6
Engine/lib/sdl/build-scripts/config.guess

@@ -1,10 +1,10 @@
 #! /bin/sh
 #! /bin/sh
 # Attempt to guess a canonical system name.
 # Attempt to guess a canonical system name.
-#   Copyright 1992-2023 Free Software Foundation, Inc.
+#   Copyright 1992-2024 Free Software Foundation, Inc.
 
 
 # shellcheck disable=SC2006,SC2268 # see below for rationale
 # shellcheck disable=SC2006,SC2268 # see below for rationale
 
 
-timestamp='2023-08-22'
+timestamp='2024-07-27'
 
 
 # This file is free software; you can redistribute it and/or modify it
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
 # under the terms of the GNU General Public License as published by
@@ -60,7 +60,7 @@ version="\
 GNU config.guess ($timestamp)
 GNU config.guess ($timestamp)
 
 
 Originally written by Per Bothner.
 Originally written by Per Bothner.
-Copyright 1992-2023 Free Software Foundation, Inc.
+Copyright 1992-2024 Free Software Foundation, Inc.
 
 
 This is free software; see the source for copying conditions.  There is NO
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -123,7 +123,7 @@ set_cc_for_build() {
     dummy=$tmp/dummy
     dummy=$tmp/dummy
     case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in
     case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in
 	,,)    echo "int x;" > "$dummy.c"
 	,,)    echo "int x;" > "$dummy.c"
-	       for driver in cc gcc c89 c99 ; do
+	       for driver in cc gcc c17 c99 c89 ; do
 		   if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
 		   if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
 		       CC_FOR_BUILD=$driver
 		       CC_FOR_BUILD=$driver
 		       break
 		       break
@@ -165,6 +165,8 @@ Linux|GNU|GNU/*)
 	LIBC=dietlibc
 	LIBC=dietlibc
 	#elif defined(__GLIBC__)
 	#elif defined(__GLIBC__)
 	LIBC=gnu
 	LIBC=gnu
+	#elif defined(__LLVM_LIBC__)
+	LIBC=llvm
 	#else
 	#else
 	#include <stdarg.h>
 	#include <stdarg.h>
 	/* First heuristic to detect musl libc.  */
 	/* First heuristic to detect musl libc.  */
@@ -632,7 +634,8 @@ EOF
 		sed 's/^		//' << EOF > "$dummy.c"
 		sed 's/^		//' << EOF > "$dummy.c"
 		#include <sys/systemcfg.h>
 		#include <sys/systemcfg.h>
 
 
-		main()
+		int
+		main ()
 			{
 			{
 			if (!__power_pc())
 			if (!__power_pc())
 				exit(1);
 				exit(1);
@@ -716,7 +719,8 @@ EOF
 		#include <stdlib.h>
 		#include <stdlib.h>
 		#include <unistd.h>
 		#include <unistd.h>
 
 
-		int main ()
+		int
+		main ()
 		{
 		{
 		#if defined(_SC_KERNEL_BITS)
 		#if defined(_SC_KERNEL_BITS)
 		    long bits = sysconf(_SC_KERNEL_BITS);
 		    long bits = sysconf(_SC_KERNEL_BITS);
@@ -1593,6 +1597,9 @@ EOF
     *:Unleashed:*:*)
     *:Unleashed:*:*)
 	GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE
 	GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE
 	;;
 	;;
+    *:Ironclad:*:*)
+	GUESS=$UNAME_MACHINE-unknown-ironclad
+	;;
 esac
 esac
 
 
 # Do we have a guess based on uname results?
 # Do we have a guess based on uname results?
@@ -1616,6 +1623,7 @@ cat > "$dummy.c" <<EOF
 #endif
 #endif
 #endif
 #endif
 #endif
 #endif
+int
 main ()
 main ()
 {
 {
 #if defined (sony)
 #if defined (sony)

File diff suppressed because it is too large
+ 563 - 173
Engine/lib/sdl/build-scripts/config.sub


+ 43 - 0
Engine/lib/sdl/build-scripts/create-release.py

@@ -0,0 +1,43 @@
+#!/usr/bin/env python3
+
+import argparse
+from pathlib import Path
+import json
+import logging
+import re
+import subprocess
+
+ROOT = Path(__file__).resolve().parents[1]
+
+
+def determine_remote() -> str:
+    text = (ROOT / "build-scripts/release-info.json").read_text()
+    release_info = json.loads(text)
+    if "remote" in release_info:
+        return release_info["remote"]
+    project_with_version = release_info["name"]
+    project, _ = re.subn("([^a-zA-Z_])", "", project_with_version)
+    return f"libsdl-org/{project}"
+
+
+def main():
+    default_remote = determine_remote()
+
+    current_commit = subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=ROOT, text=True).strip()
+
+    parser = argparse.ArgumentParser(allow_abbrev=False)
+    parser.add_argument("--ref", required=True, help=f"Name of branch or tag containing release.yml")
+    parser.add_argument("--remote", "-R", default=default_remote, help=f"Remote repo (default={default_remote})")
+    parser.add_argument("--commit", default=current_commit, help=f"Commit (default={current_commit})")
+    args = parser.parse_args()
+
+
+    print(f"Running release.yml workflow:")
+    print(f"  commit = {args.commit}")
+    print(f"  remote = {args.remote}")
+
+    subprocess.check_call(["gh", "-R", args.remote, "workflow", "run", "release.yml", "--ref", args.ref, "-f", f"commit={args.commit}"], cwd=ROOT)
+
+
+if __name__ == "__main__":
+    raise SystemExit(main())

+ 2 - 2
Engine/lib/sdl/build-scripts/gen_audio_channel_conversion.c

@@ -1,6 +1,6 @@
 /*
 /*
   Simple DirectMedia Layer
   Simple DirectMedia Layer
-  Copyright (C) 1997-2023 Sam Lantinga <[email protected]>
+  Copyright (C) 1997-2025 Sam Lantinga <[email protected]>
 
 
   This software is provided 'as-is', without any express or implied
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
   warranty.  In no event will the authors be held liable for any damages
@@ -395,7 +395,7 @@ int main(void)
     printf(
     printf(
         "/*\n"
         "/*\n"
         "  Simple DirectMedia Layer\n"
         "  Simple DirectMedia Layer\n"
-        "  Copyright (C) 1997-2023 Sam Lantinga <[email protected]>\n"
+        "  Copyright (C) 1997-2025 Sam Lantinga <[email protected]>\n"
         "\n"
         "\n"
         "  This software is provided 'as-is', without any express or implied\n"
         "  This software is provided 'as-is', without any express or implied\n"
         "  warranty.  In no event will the authors be held liable for any damages\n"
         "  warranty.  In no event will the authors be held liable for any damages\n"

+ 2 - 2
Engine/lib/sdl/build-scripts/gen_audio_resampler_filter.c

@@ -1,6 +1,6 @@
 /*
 /*
   Simple DirectMedia Layer
   Simple DirectMedia Layer
-  Copyright (C) 1997-2023 Sam Lantinga <[email protected]>
+  Copyright (C) 1997-2025 Sam Lantinga <[email protected]>
 
 
   This software is provided 'as-is', without any express or implied
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
   warranty.  In no event will the authors be held liable for any damages
@@ -113,7 +113,7 @@ int main(void)
     printf(
     printf(
         "/*\n"
         "/*\n"
         "  Simple DirectMedia Layer\n"
         "  Simple DirectMedia Layer\n"
-        "  Copyright (C) 1997-2023 Sam Lantinga <[email protected]>\n"
+        "  Copyright (C) 1997-2025 Sam Lantinga <[email protected]>\n"
         "\n"
         "\n"
         "  This software is provided 'as-is', without any express or implied\n"
         "  This software is provided 'as-is', without any express or implied\n"
         "  warranty.  In no event will the authors be held liable for any damages\n"
         "  warranty.  In no event will the authors be held liable for any damages\n"

+ 70 - 52
Engine/lib/sdl/build-scripts/ltmain.sh

@@ -2415,10 +2415,10 @@ libtool_validate_options ()
     # preserve --debug
     # preserve --debug
     test : = "$debug_cmd" || func_append preserve_args " --debug"
     test : = "$debug_cmd" || func_append preserve_args " --debug"
 
 
-    case $host in
+    case $host_os in
       # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452
       # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452
       # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788
       # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788
-      *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*)
+      cygwin* | mingw* | windows* | pw32* | cegcc* | solaris2* | os2*)
         # don't eliminate duplications in $postdeps and $predeps
         # don't eliminate duplications in $postdeps and $predeps
         opt_duplicate_compiler_generated_deps=:
         opt_duplicate_compiler_generated_deps=:
         ;;
         ;;
@@ -2750,7 +2750,7 @@ EOF
 
 
 # func_convert_core_file_wine_to_w32 ARG
 # func_convert_core_file_wine_to_w32 ARG
 # Helper function used by file name conversion functions when $build is *nix,
 # Helper function used by file name conversion functions when $build is *nix,
-# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# and $host is mingw, windows, cygwin, or some other w32 environment. Relies on a
 # correctly configured wine environment available, with the winepath program
 # correctly configured wine environment available, with the winepath program
 # in $build's $PATH.
 # in $build's $PATH.
 #
 #
@@ -2782,9 +2782,10 @@ func_convert_core_file_wine_to_w32 ()
 
 
 # func_convert_core_path_wine_to_w32 ARG
 # func_convert_core_path_wine_to_w32 ARG
 # Helper function used by path conversion functions when $build is *nix, and
 # Helper function used by path conversion functions when $build is *nix, and
-# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
-# configured wine environment available, with the winepath program in $build's
-# $PATH. Assumes ARG has no leading or trailing path separator characters.
+# $host is mingw, windows, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH. Assumes ARG has no leading or trailing path separator
+# characters.
 #
 #
 # ARG is path to be converted from $build format to win32.
 # ARG is path to be converted from $build format to win32.
 # Result is available in $func_convert_core_path_wine_to_w32_result.
 # Result is available in $func_convert_core_path_wine_to_w32_result.
@@ -3439,7 +3440,7 @@ func_mode_compile ()
 
 
     # On Cygwin there's no "real" PIC flag so we must build both object types
     # On Cygwin there's no "real" PIC flag so we must build both object types
     case $host_os in
     case $host_os in
-    cygwin* | mingw* | pw32* | os2* | cegcc*)
+    cygwin* | mingw* | windows* | pw32* | os2* | cegcc*)
       pic_mode=default
       pic_mode=default
       ;;
       ;;
     esac
     esac
@@ -4316,7 +4317,7 @@ func_mode_install ()
 	      'exit $?'
 	      'exit $?'
 	  tstripme=$stripme
 	  tstripme=$stripme
 	  case $host_os in
 	  case $host_os in
-	  cygwin* | mingw* | pw32* | cegcc*)
+	  cygwin* | mingw* | windows* | pw32* | cegcc*)
 	    case $realname in
 	    case $realname in
 	    *.dll.a)
 	    *.dll.a)
 	      tstripme=
 	      tstripme=
@@ -4429,7 +4430,7 @@ func_mode_install ()
 
 
 	# Do a test to see if this is really a libtool program.
 	# Do a test to see if this is really a libtool program.
 	case $host in
 	case $host in
-	*cygwin* | *mingw*)
+	*cygwin* | *mingw* | *windows*)
 	    if func_ltwrapper_executable_p "$file"; then
 	    if func_ltwrapper_executable_p "$file"; then
 	      func_ltwrapper_scriptname "$file"
 	      func_ltwrapper_scriptname "$file"
 	      wrapper=$func_ltwrapper_scriptname_result
 	      wrapper=$func_ltwrapper_scriptname_result
@@ -4657,7 +4658,7 @@ extern \"C\" {
 	      $RM $export_symbols
 	      $RM $export_symbols
 	      eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
 	      eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
 	      case $host in
 	      case $host in
-	      *cygwin* | *mingw* | *cegcc* )
+	      *cygwin* | *mingw* | *windows* | *cegcc* )
                 eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
                 eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
                 eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
                 eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
 	        ;;
 	        ;;
@@ -4669,7 +4670,7 @@ extern \"C\" {
 	      eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
 	      eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
 	      eval '$MV "$nlist"T "$nlist"'
 	      eval '$MV "$nlist"T "$nlist"'
 	      case $host in
 	      case $host in
-	        *cygwin* | *mingw* | *cegcc* )
+	        *cygwin* | *mingw* | *windows* | *cegcc* )
 	          eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
 	          eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
 	          eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
 	          eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
 	          ;;
 	          ;;
@@ -4683,7 +4684,7 @@ extern \"C\" {
 	  func_basename "$dlprefile"
 	  func_basename "$dlprefile"
 	  name=$func_basename_result
 	  name=$func_basename_result
           case $host in
           case $host in
-	    *cygwin* | *mingw* | *cegcc* )
+	    *cygwin* | *mingw* | *windows* | *cegcc* )
 	      # if an import library, we need to obtain dlname
 	      # if an import library, we need to obtain dlname
 	      if func_win32_import_lib_p "$dlprefile"; then
 	      if func_win32_import_lib_p "$dlprefile"; then
 	        func_tr_sh "$dlprefile"
 	        func_tr_sh "$dlprefile"
@@ -4858,7 +4859,7 @@ static const void *lt_preloaded_setup() {
 	# Transform the symbol file into the correct name.
 	# Transform the symbol file into the correct name.
 	symfileobj=$output_objdir/${my_outputname}S.$objext
 	symfileobj=$output_objdir/${my_outputname}S.$objext
 	case $host in
 	case $host in
-	*cygwin* | *mingw* | *cegcc* )
+	*cygwin* | *mingw* | *windows* | *cegcc* )
 	  if test -f "$output_objdir/$my_outputname.def"; then
 	  if test -f "$output_objdir/$my_outputname.def"; then
 	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
 	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
 	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
 	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
@@ -4934,7 +4935,7 @@ func_win32_libid ()
   *ar\ archive*) # could be an import, or static
   *ar\ archive*) # could be an import, or static
     # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
     # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
     if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
     if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
-       $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+       $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64|pe-aarch64)' >/dev/null; then
       case $nm_interface in
       case $nm_interface in
       "MS dumpbin")
       "MS dumpbin")
 	if func_cygming_ms_implib_p "$1" ||
 	if func_cygming_ms_implib_p "$1" ||
@@ -5201,7 +5202,7 @@ func_extract_archives ()
 #
 #
 # Emit a libtool wrapper script on stdout.
 # Emit a libtool wrapper script on stdout.
 # Don't directly open a file because we may want to
 # Don't directly open a file because we may want to
-# incorporate the script contents within a cygwin/mingw
+# incorporate the script contents within a cygwin/mingw/windows
 # wrapper executable.  Must ONLY be called from within
 # wrapper executable.  Must ONLY be called from within
 # func_mode_link because it depends on a number of variables
 # func_mode_link because it depends on a number of variables
 # set therein.
 # set therein.
@@ -5209,7 +5210,7 @@ func_extract_archives ()
 # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
 # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
 # variable will take.  If 'yes', then the emitted script
 # variable will take.  If 'yes', then the emitted script
 # will assume that the directory where it is stored is
 # will assume that the directory where it is stored is
-# the $objdir directory.  This is a cygwin/mingw-specific
+# the $objdir directory.  This is a cygwin/mingw/windows-specific
 # behavior.
 # behavior.
 func_emit_wrapper ()
 func_emit_wrapper ()
 {
 {
@@ -5333,7 +5334,7 @@ func_exec_program_core ()
 "
 "
   case $host in
   case $host in
   # Backslashes separate directories on plain windows
   # Backslashes separate directories on plain windows
-  *-*-mingw | *-*-os2* | *-cegcc*)
+  *-*-mingw* | *-*-windows* | *-*-os2* | *-cegcc*)
     $ECHO "\
     $ECHO "\
       if test -n \"\$lt_option_debug\"; then
       if test -n \"\$lt_option_debug\"; then
         \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2
         \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2
@@ -5401,7 +5402,7 @@ func_exec_program ()
     file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
     file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
   done
   done
 
 
-  # Usually 'no', except on cygwin/mingw when embedded into
+  # Usually 'no', except on cygwin/mingw/windows when embedded into
   # the cwrapper.
   # the cwrapper.
   WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
   WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
   if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
   if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
@@ -5533,7 +5534,7 @@ EOF
 #endif
 #endif
 #include <stdio.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
-#ifdef _MSC_VER
+#if defined _WIN32 && !defined __GNUC__
 # include <direct.h>
 # include <direct.h>
 # include <process.h>
 # include <process.h>
 # include <io.h>
 # include <io.h>
@@ -5558,7 +5559,7 @@ EOF
 /* declarations of non-ANSI functions */
 /* declarations of non-ANSI functions */
 #if defined __MINGW32__
 #if defined __MINGW32__
 # ifdef __STRICT_ANSI__
 # ifdef __STRICT_ANSI__
-int _putenv (const char *);
+_CRTIMP int __cdecl _putenv (const char *);
 # endif
 # endif
 #elif defined __CYGWIN__
 #elif defined __CYGWIN__
 # ifdef __STRICT_ANSI__
 # ifdef __STRICT_ANSI__
@@ -5756,7 +5757,7 @@ main (int argc, char *argv[])
 	{
 	{
 EOF
 EOF
 	    case $host in
 	    case $host in
-	      *mingw* | *cygwin* )
+	      *mingw* | *windows* | *cygwin* )
 		# make stdout use "unix" line endings
 		# make stdout use "unix" line endings
 		echo "          setmode(1,_O_BINARY);"
 		echo "          setmode(1,_O_BINARY);"
 		;;
 		;;
@@ -5859,7 +5860,7 @@ EOF
 EOF
 EOF
 
 
 	    case $host_os in
 	    case $host_os in
-	      mingw*)
+	      mingw* | windows*)
 	    cat <<"EOF"
 	    cat <<"EOF"
   {
   {
     char* p;
     char* p;
@@ -5901,7 +5902,7 @@ EOF
 EOF
 EOF
 
 
 	    case $host_os in
 	    case $host_os in
-	      mingw*)
+	      mingw* | windows*)
 		cat <<"EOF"
 		cat <<"EOF"
   /* execv doesn't actually work on mingw as expected on unix */
   /* execv doesn't actually work on mingw as expected on unix */
   newargz = prepare_spawn (newargz);
   newargz = prepare_spawn (newargz);
@@ -6320,7 +6321,7 @@ lt_update_lib_path (const char *name, const char *value)
 
 
 EOF
 EOF
 	    case $host_os in
 	    case $host_os in
-	      mingw*)
+	      mingw* | windows*)
 		cat <<"EOF"
 		cat <<"EOF"
 
 
 /* Prepares an argument vector before calling spawn().
 /* Prepares an argument vector before calling spawn().
@@ -6495,12 +6496,12 @@ func_mode_link ()
     $debug_cmd
     $debug_cmd
 
 
     case $host in
     case $host in
-    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+    *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-cegcc*)
       # It is impossible to link a dll without this setting, and
       # It is impossible to link a dll without this setting, and
       # we shouldn't force the makefile maintainer to figure out
       # we shouldn't force the makefile maintainer to figure out
       # what system we are compiling for in order to pass an extra
       # what system we are compiling for in order to pass an extra
       # flag for every libtool invocation.
       # flag for every libtool invocation.
-      # SDL customization: SDL code doesn't have any undefined symbols
+      # SDL customization: SDL code doesn't have any undefined symbols.
       allow_undefined=no
       allow_undefined=no
 
 
       # FIXME: Unfortunately, there are problems with the above when trying
       # FIXME: Unfortunately, there are problems with the above when trying
@@ -6508,7 +6509,7 @@ func_mode_link ()
       # even a static library is built.  For now, we need to specify
       # even a static library is built.  For now, we need to specify
       # -no-undefined on the libtool link line when we can be certain
       # -no-undefined on the libtool link line when we can be certain
       # that all symbols are satisfied, otherwise we get a static library.
       # that all symbols are satisfied, otherwise we get a static library.
-      # SDL customization: SDL code doesn't have any undefined symbols
+      # SDL customization: SDL code doesn't have any undefined symbols.
       # allow_undefined=yes
       # allow_undefined=yes
       ;;
       ;;
     *)
     *)
@@ -7003,7 +7004,7 @@ func_mode_link ()
 	  ;;
 	  ;;
 	esac
 	esac
 	case $host in
 	case $host in
-	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+	*-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-cegcc*)
 	  testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
 	  testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
 	  case :$dllsearchpath: in
 	  case :$dllsearchpath: in
 	  *":$dir:"*) ;;
 	  *":$dir:"*) ;;
@@ -7023,7 +7024,7 @@ func_mode_link ()
       -l*)
       -l*)
 	if test X-lc = "X$arg" || test X-lm = "X$arg"; then
 	if test X-lc = "X$arg" || test X-lm = "X$arg"; then
 	  case $host in
 	  case $host in
-	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
+	  *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
 	    # These systems don't actually have a C or math library (as such)
 	    # These systems don't actually have a C or math library (as such)
 	    continue
 	    continue
 	    ;;
 	    ;;
@@ -7095,7 +7096,7 @@ func_mode_link ()
 	continue
 	continue
 	;;
 	;;
       -mt|-mthreads|-kthread|-Kthread|-pthreads|--thread-safe \
       -mt|-mthreads|-kthread|-Kthread|-pthreads|--thread-safe \
-      |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+      |-threads|-fopenmp|-fopenmp=*|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
 	func_append compiler_flags " $arg"
 	func_append compiler_flags " $arg"
 	func_append compile_command " $arg"
 	func_append compile_command " $arg"
 	func_append finalize_command " $arg"
 	func_append finalize_command " $arg"
@@ -7118,7 +7119,7 @@ func_mode_link ()
 
 
       -no-install)
       -no-install)
 	case $host in
 	case $host in
-	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+	*-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
 	  # The PATH hackery in wrapper scripts is required on Windows
 	  # The PATH hackery in wrapper scripts is required on Windows
 	  # and Darwin in order for the loader to find any dlls it needs.
 	  # and Darwin in order for the loader to find any dlls it needs.
 	  func_warning "'-no-install' is ignored for $host"
 	  func_warning "'-no-install' is ignored for $host"
@@ -7303,13 +7304,29 @@ func_mode_link ()
       # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
       # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
       # -specs=*             GCC specs files
       # -specs=*             GCC specs files
       # -stdlib=*            select c++ std lib with clang
       # -stdlib=*            select c++ std lib with clang
+      # -fdiagnostics-color* simply affects output
+      # -frecord-gcc-switches used to verify flags were respected
       # -fsanitize=*         Clang/GCC memory and address sanitizer
       # -fsanitize=*         Clang/GCC memory and address sanitizer
+      # -fno-sanitize*       Clang/GCC memory and address sanitizer
+      # -shared-libsan       Link with shared sanitizer runtimes (Clang)
+      # -static-libsan       Link with static sanitizer runtimes (Clang)
+      # -no-canonical-prefixes Do not expand any symbolic links
       # -fuse-ld=*           Linker select flags for GCC
       # -fuse-ld=*           Linker select flags for GCC
+      # -static-*            direct GCC to link specific libraries statically
+      # -fcilkplus           Cilk Plus language extension features for C/C++
+      # -rtlib=*             select c runtime lib with clang
+      # --unwindlib=*        select unwinder library with clang
+      # -f{file|debug|macro|profile}-prefix-map=* needed for lto linking
       # -Wa,*                Pass flags directly to the assembler
       # -Wa,*                Pass flags directly to the assembler
+      # -Werror, -Werror=*   Report (specified) warnings as errors
       -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
       -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
       -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
       -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
-      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
-      -specs=*|-fsanitize=*|-fuse-ld=*|-Wa,*)
+      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-no-canonical-prefixes| \
+      -stdlib=*|-rtlib=*|--unwindlib=*| \
+      -specs=*|-fsanitize=*|-fno-sanitize*|-shared-libsan|-static-libsan| \
+      -ffile-prefix-map=*|-fdebug-prefix-map=*|-fmacro-prefix-map=*|-fprofile-prefix-map=*| \
+      -fdiagnostics-color*|-frecord-gcc-switches| \
+      -fuse-ld=*|-static-*|-fcilkplus|-Wa,*|-Werror|-Werror=*)
         func_quote_for_eval "$arg"
         func_quote_for_eval "$arg"
 	arg=$func_quote_for_eval_result
 	arg=$func_quote_for_eval_result
         func_append compile_command " $arg"
         func_append compile_command " $arg"
@@ -7639,7 +7656,7 @@ func_mode_link ()
 	found=false
 	found=false
 	case $deplib in
 	case $deplib in
 	-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
 	-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
-        |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+        |-threads|-fopenmp|-fopenmp=*|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
 	  if test prog,link = "$linkmode,$pass"; then
 	  if test prog,link = "$linkmode,$pass"; then
 	    compile_deplibs="$deplib $compile_deplibs"
 	    compile_deplibs="$deplib $compile_deplibs"
 	    finalize_deplibs="$deplib $finalize_deplibs"
 	    finalize_deplibs="$deplib $finalize_deplibs"
@@ -8022,7 +8039,7 @@ func_mode_link ()
 	  fi
 	  fi
 	  case $host in
 	  case $host in
 	    # special handling for platforms with PE-DLLs.
 	    # special handling for platforms with PE-DLLs.
-	    *cygwin* | *mingw* | *cegcc* )
+	    *cygwin* | *mingw* | *windows* | *cegcc* )
 	      # Linker will automatically link against shared library if both
 	      # Linker will automatically link against shared library if both
 	      # static and shared are present.  Therefore, ensure we extract
 	      # static and shared are present.  Therefore, ensure we extract
 	      # symbols from the import library if a shared library is present
 	      # symbols from the import library if a shared library is present
@@ -8165,8 +8182,8 @@ func_mode_link ()
 	fi
 	fi
 	if test -n "$library_names" &&
 	if test -n "$library_names" &&
 	   { test no = "$use_static_libs" || test -z "$old_library"; }; then
 	   { test no = "$use_static_libs" || test -z "$old_library"; }; then
-	  case $host in
-	  *cygwin* | *mingw* | *cegcc* | *os2*)
+	  case $host_os in
+	  cygwin* | mingw* | windows* | cegcc* | os2*)
 	      # No point in relinking DLLs because paths are not encoded
 	      # No point in relinking DLLs because paths are not encoded
 	      func_append notinst_deplibs " $lib"
 	      func_append notinst_deplibs " $lib"
 	      need_relink=no
 	      need_relink=no
@@ -8235,8 +8252,8 @@ func_mode_link ()
 	      soname=$dlname
 	      soname=$dlname
 	    elif test -n "$soname_spec"; then
 	    elif test -n "$soname_spec"; then
 	      # bleh windows
 	      # bleh windows
-	      case $host in
-	      *cygwin* | mingw* | *cegcc*)  # | *os2* # SDL customization: removed OS/2 versioning support.
+	      case $host_os in
+	      cygwin* | mingw* | windows* | cegcc*) # | os2* # SDL customization: removed OS/2 versioning support.
 	        func_arith $current - $age
 	        func_arith $current - $age
 		major=$func_arith_result
 		major=$func_arith_result
 		versuffix=-$major
 		versuffix=-$major
@@ -8378,7 +8395,7 @@ func_mode_link ()
 	       test no = "$hardcode_direct_absolute"; then
 	       test no = "$hardcode_direct_absolute"; then
 	      add=$libdir/$linklib
 	      add=$libdir/$linklib
 	    elif test yes = "$hardcode_minus_L"; then
 	    elif test yes = "$hardcode_minus_L"; then
-	      add_dir=-L$libdir
+	      add_dir=-L$lt_sysroot$libdir
 	      add=-l$name
 	      add=-l$name
 	    elif test yes = "$hardcode_shlibpath_var"; then
 	    elif test yes = "$hardcode_shlibpath_var"; then
 	      case :$finalize_shlibpath: in
 	      case :$finalize_shlibpath: in
@@ -8395,7 +8412,7 @@ func_mode_link ()
 	      fi
 	      fi
 	    else
 	    else
 	      # We cannot seem to hardcode it, guess we'll fake it.
 	      # We cannot seem to hardcode it, guess we'll fake it.
-	      add_dir=-L$libdir
+	      add_dir=-L$lt_sysroot$libdir
 	      # Try looking first in the location we're being installed to.
 	      # Try looking first in the location we're being installed to.
 	      if test -n "$inst_prefix_dir"; then
 	      if test -n "$inst_prefix_dir"; then
 		case $libdir in
 		case $libdir in
@@ -8666,7 +8683,7 @@ func_mode_link ()
       test CXX = "$tagname" && {
       test CXX = "$tagname" && {
         case $host_os in
         case $host_os in
         linux*)
         linux*)
-          case `$CC -V 2>&1 | sed 5q` in
+          case `$CC -V 2>&1 | $SED 5q` in
           *Sun\ C*) # Sun C++ 5.9
           *Sun\ C*) # Sun C++ 5.9
             func_suncc_cstd_abi
             func_suncc_cstd_abi
 
 
@@ -8839,13 +8856,13 @@ func_mode_link ()
 	  #
 	  #
 	  case $version_type in
 	  case $version_type in
 	  # correct linux to gnu/linux during the next big refactor
 	  # correct linux to gnu/linux during the next big refactor
-	  darwin|freebsd-elf|linux|midnightbsd-elf|osf|windows|none)
+	  darwin|freebsd-elf|linux|midnightbsd-elf|osf|qnx|windows|none)
 	    func_arith $number_major + $number_minor
 	    func_arith $number_major + $number_minor
 	    current=$func_arith_result
 	    current=$func_arith_result
 	    age=$number_minor
 	    age=$number_minor
 	    revision=$number_revision
 	    revision=$number_revision
 	    ;;
 	    ;;
-	  freebsd-aout|qnx|sunos)
+	  freebsd-aout|sco|sunos)
 	    current=$number_major
 	    current=$number_major
 	    revision=$number_minor
 	    revision=$number_minor
 	    age=0
 	    age=0
@@ -8992,8 +9009,9 @@ func_mode_link ()
 	  ;;
 	  ;;
 
 
 	qnx)
 	qnx)
-	  major=.$current
-	  versuffix=.$current
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix=$major.$age.$revision
 	  ;;
 	  ;;
 
 
 	sco)
 	sco)
@@ -9146,7 +9164,7 @@ func_mode_link ()
       if test yes = "$build_libtool_libs"; then
       if test yes = "$build_libtool_libs"; then
 	if test -n "$rpath"; then
 	if test -n "$rpath"; then
 	  case $host in
 	  case $host in
-	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
+	  *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
 	    # these systems don't actually have a c library (as such)!
 	    # these systems don't actually have a c library (as such)!
 	    ;;
 	    ;;
 	  *-*-rhapsody* | *-*-darwin1.[012])
 	  *-*-rhapsody* | *-*-darwin1.[012])
@@ -9660,7 +9678,7 @@ EOF
 
 
 	orig_export_symbols=
 	orig_export_symbols=
 	case $host_os in
 	case $host_os in
-	cygwin* | mingw* | cegcc*)
+	cygwin* | mingw* | windows* | cegcc*)
 	  if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
 	  if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
 	    # exporting using user supplied symfile
 	    # exporting using user supplied symfile
 	    func_dll_def_p "$export_symbols" || {
 	    func_dll_def_p "$export_symbols" || {
@@ -10330,7 +10348,7 @@ EOF
 	  esac
 	  esac
 	fi
 	fi
 	case $host in
 	case $host in
-	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+	*-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-cegcc*)
 	  testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'`
 	  testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'`
 	  case :$dllsearchpath: in
 	  case :$dllsearchpath: in
 	  *":$libdir:"*) ;;
 	  *":$libdir:"*) ;;
@@ -10408,7 +10426,7 @@ EOF
         # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
         # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
         wrappers_required=false
         wrappers_required=false
         ;;
         ;;
-      *cygwin* | *mingw* )
+      *cygwin* | *mingw* | *windows* )
         test yes = "$build_libtool_libs" || wrappers_required=false
         test yes = "$build_libtool_libs" || wrappers_required=false
         ;;
         ;;
       *)
       *)
@@ -10561,7 +10579,7 @@ EOF
 	  *) exeext= ;;
 	  *) exeext= ;;
 	esac
 	esac
 	case $host in
 	case $host in
-	  *cygwin* | *mingw* )
+	  *cygwin* | *mingw* | windows* )
 	    func_dirname_and_basename "$output" "" "."
 	    func_dirname_and_basename "$output" "" "."
 	    output_name=$func_basename_result
 	    output_name=$func_basename_result
 	    output_path=$func_dirname_result
 	    output_path=$func_dirname_result
@@ -10893,7 +10911,7 @@ EOF
 	  # tests/bindir.at for full details.
 	  # tests/bindir.at for full details.
 	  tdlname=$dlname
 	  tdlname=$dlname
 	  case $host,$output,$installed,$module,$dlname in
 	  case $host,$output,$installed,$module,$dlname in
-	    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+	    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *windows*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
 	      # If a -bindir argument was supplied, place the dll there.
 	      # If a -bindir argument was supplied, place the dll there.
 	      if test -n "$bindir"; then
 	      if test -n "$bindir"; then
 		func_relative_path "$install_libdir" "$bindir"
 		func_relative_path "$install_libdir" "$bindir"

+ 108 - 0
Engine/lib/sdl/build-scripts/release-info.json

@@ -0,0 +1,108 @@
+{
+  "name": "SDL2",
+  "remote": "libsdl-org/SDL",
+  "version": {
+    "file": "include/SDL_version.h",
+    "re_major": "^#define SDL_MAJOR_VERSION\\s+([0-9]+)$",
+    "re_minor": "^#define SDL_MINOR_VERSION\\s+([0-9]+)$",
+    "re_micro": "^#define SDL_PATCHLEVEL\\s+([0-9]+)$"
+  },
+  "source": {
+    "checks": [
+      "src/SDL.c",
+      "include/SDL.h",
+      "test/testsprite2.c",
+      "android-project/app/src/main/java/org/libsdl/app/SDLActivity.java"
+    ]
+  },
+  "dmg": {
+    "project": "Xcode/SDL/SDL.xcodeproj",
+    "path": "Xcode/SDL/build/SDL2.dmg",
+    "target": "Standard DMG"
+  },
+  "mingw": {
+    "autotools": {
+      "archs": ["x86", "x64"],
+      "args": [
+      ],
+      "files": {
+        "@<@TRIPLET@>@/include/SDL2": [
+          "include/SDL_config*.h"
+        ]
+      }
+    },
+    "files": {
+      "": [
+        "mingw/pkg-support/INSTALL.txt",
+        "mingw/pkg-support/Makefile",
+        "BUGS.txt",
+        "CREDITS.txt",
+        "README-SDL.txt",
+        "WhatsNew.txt",
+        "LICENSE.txt",
+        "README.md"
+      ],
+      "cmake": [
+        "mingw/pkg-support/cmake/sdl2-config.cmake",
+        "mingw/pkg-support/cmake/sdl2-config-version.cmake"
+      ],
+      "docs": [
+        "docs/*"
+      ],
+      "test": [
+        "test/*"
+      ]
+    }
+  },
+  "msvc": {
+    "msbuild": {
+      "archs": [
+        "x86",
+        "x64"
+      ],
+      "projects": [
+        "VisualC/SDL/SDL.vcxproj",
+        "VisualC/SDLmain/SDLmain.vcxproj",
+        "VisualC/SDLtest/SDLtest.vcxproj"
+      ],
+      "files-lib": {
+        "": [
+          "VisualC/SDL/@<@PLATFORM@>@/@<@CONFIGURATION@>@/SDL2.dll"
+        ]
+      },
+      "files-devel": {
+        "lib/@<@ARCH@>@": [
+          "VisualC/SDL/@<@PLATFORM@>@/@<@CONFIGURATION@>@/SDL2.dll",
+          "VisualC/SDL/@<@PLATFORM@>@/@<@CONFIGURATION@>@/SDL2.lib",
+          "VisualC/SDL/@<@PLATFORM@>@/@<@CONFIGURATION@>@/SDL2.pdb",
+          "VisualC/SDLmain/@<@PLATFORM@>@/@<@CONFIGURATION@>@/SDL2main.lib",
+          "VisualC/SDLtest/@<@PLATFORM@>@/@<@CONFIGURATION@>@/SDL2test.lib"
+        ]
+      }
+    },
+    "files-lib": {
+      "": [
+        "README-SDL.txt"
+      ]
+    },
+    "files-devel": {
+      "": [
+        "README-SDL.txt",
+        "BUGS.txt",
+        "LICENSE.txt",
+        "README.md",
+        "WhatsNew.txt"
+      ],
+      "cmake": [
+        "VisualC/pkg-support/cmake/sdl2-config.cmake",
+        "VisualC/pkg-support/cmake/sdl2-config-version.cmake"
+      ],
+      "docs": [
+        "docs/*"
+      ],
+      "include": [
+        "include/*.h"
+      ]
+    }
+  }
+}

+ 303 - 0
Engine/lib/sdl/build-scripts/setup-gdk-desktop.py

@@ -0,0 +1,303 @@
+#!/usr/bin/env python
+
+import argparse
+import functools
+import logging
+import os
+from pathlib import Path
+import re
+import shutil
+import subprocess
+import tempfile
+import textwrap
+import urllib.request
+import zipfile
+
+# Update both variables when updating the GDK
+GIT_REF = "June_2024_Update_1"
+GDK_EDITION = "240601"  # YYMMUU
+
+logger = logging.getLogger(__name__)
+
+class GdDesktopConfigurator:
+    def __init__(self, gdk_path, arch, vs_folder, vs_version=None, vs_toolset=None, temp_folder=None, git_ref=None, gdk_edition=None):
+        self.git_ref = git_ref or GIT_REF
+        self.gdk_edition = gdk_edition or GDK_EDITION
+        self.gdk_path = gdk_path
+        self.temp_folder = temp_folder or Path(tempfile.gettempdir())
+        self.dl_archive_path = Path(self.temp_folder) / f"{ self.git_ref }.zip"
+        self.gdk_extract_path = Path(self.temp_folder) / f"GDK-{ self.git_ref }"
+        self.arch = arch
+        self.vs_folder = vs_folder
+        self._vs_version = vs_version
+        self._vs_toolset = vs_toolset
+
+    def download_archive(self) -> None:
+        gdk_url = f"https://github.com/microsoft/GDK/archive/refs/tags/{ GIT_REF }.zip"
+        logger.info("Downloading %s to %s", gdk_url, self.dl_archive_path)
+        urllib.request.urlretrieve(gdk_url, self.dl_archive_path)
+        assert self.dl_archive_path.is_file()
+
+    def extract_zip_archive(self) -> None:
+        extract_path = self.gdk_extract_path.parent
+        assert self.dl_archive_path.is_file()
+        logger.info("Extracting %s to %s", self.dl_archive_path, extract_path)
+        with zipfile.ZipFile(self.dl_archive_path) as zf:
+            zf.extractall(extract_path)
+        assert self.gdk_extract_path.is_dir(), f"{self.gdk_extract_path} must exist"
+
+    def extract_development_kit(self) -> None:
+        extract_dks_cmd = self.gdk_extract_path / "SetupScripts/ExtractXboxOneDKs.cmd"
+        assert extract_dks_cmd.is_file()
+        logger.info("Extracting GDK Development Kit: running %s", extract_dks_cmd)
+        cmd = ["cmd.exe", "/C", str(extract_dks_cmd), str(self.gdk_extract_path), str(self.gdk_path)]
+        logger.debug("Running %r", cmd)
+        subprocess.check_call(cmd)
+
+    def detect_vs_version(self) -> str:
+        vs_regex = re.compile("VS([0-9]{4})")
+        supported_vs_versions = []
+        for p in self.gaming_grdk_build_path.iterdir():
+            if not p.is_dir():
+                continue
+            if m := vs_regex.match(p.name):
+                supported_vs_versions.append(m.group(1))
+        logger.info(f"Supported Visual Studio versions: {supported_vs_versions}")
+        vs_versions = set(self.vs_folder.parts).intersection(set(supported_vs_versions))
+        if not vs_versions:
+            raise RuntimeError("Visual Studio version is incompatible")
+        if len(vs_versions) > 1:
+            raise RuntimeError(f"Too many compatible VS versions found ({vs_versions})")
+        vs_version = vs_versions.pop()
+        logger.info(f"Used Visual Studio version: {vs_version}")
+        return vs_version
+
+    def detect_vs_toolset(self) -> str:
+        toolset_paths = []
+        for ts_path in self.gdk_toolset_parent_path.iterdir():
+            if not ts_path.is_dir():
+                continue
+            ms_props = ts_path / "Microsoft.Cpp.props"
+            if not ms_props.is_file():
+                continue
+            toolset_paths.append(ts_path.name)
+        logger.info("Detected Visual Studio toolsets: %s", toolset_paths)
+        assert toolset_paths, "Have we detected at least one toolset?"
+
+        def toolset_number(toolset: str) -> int:
+            if m:= re.match("[^0-9]*([0-9]+).*", toolset):
+                return int(m.group(1))
+            return -9
+
+        return max(toolset_paths, key=toolset_number)
+
+    @property
+    def vs_version(self) -> str:
+        if self._vs_version is None:
+            self._vs_version = self.detect_vs_version()
+        return self._vs_version
+
+    @property
+    def vs_toolset(self) -> str:
+        if self._vs_toolset is None:
+            self._vs_toolset = self.detect_vs_toolset()
+        return self._vs_toolset
+
+    @staticmethod
+    def copy_files_and_merge_into(srcdir: Path, dstdir: Path) -> None:
+        logger.info(f"Copy {srcdir} to {dstdir}")
+        for root, _, files in os.walk(srcdir):
+            dest_root = dstdir / Path(root).relative_to(srcdir)
+            if not dest_root.is_dir():
+                dest_root.mkdir()
+            for file in files:
+                srcfile = Path(root) / file
+                dstfile = dest_root / file
+                shutil.copy(srcfile, dstfile)
+
+    def copy_msbuild(self) -> None:
+        vc_toolset_parent_path = self.vs_folder / "MSBuild/Microsoft/VC"
+        if 1:
+            logger.info(f"Detected compatible Visual Studio version: {self.vs_version}")
+            srcdir = vc_toolset_parent_path
+            dstdir = self.gdk_toolset_parent_path
+            assert srcdir.is_dir(), "Source directory must exist"
+            assert dstdir.is_dir(), "Destination directory must exist"
+
+            self.copy_files_and_merge_into(srcdir=srcdir, dstdir=dstdir)
+
+    @property
+    def game_dk_path(self) -> Path:
+        return self.gdk_path / "Microsoft GDK"
+
+    @property
+    def game_dk_latest_path(self) -> Path:
+        return self.game_dk_path / self.gdk_edition
+
+    @property
+    def windows_sdk_path(self) -> Path:
+        return self.gdk_path / "Windows Kits/10"
+
+    @property
+    def gaming_grdk_build_path(self) -> Path:
+        return self.game_dk_latest_path / "GRDK"
+
+    @property
+    def gdk_toolset_parent_path(self) -> Path:
+        return self.gaming_grdk_build_path / f"VS{self.vs_version}/flatDeployment/MSBuild/Microsoft/VC"
+
+    @property
+    def env(self) -> dict[str, str]:
+        game_dk = self.game_dk_path
+        game_dk_latest = self.game_dk_latest_path
+        windows_sdk_dir = self.windows_sdk_path
+        gaming_grdk_build = self.gaming_grdk_build_path
+
+        return {
+            "GRDKEDITION": f"{self.gdk_edition}",
+            "GameDK": f"{game_dk}\\",
+            "GameDKLatest": f"{ game_dk_latest }\\",
+            "WindowsSdkDir": f"{ windows_sdk_dir }\\",
+            "GamingGRDKBuild": f"{ gaming_grdk_build }\\",
+            "VSInstallDir": f"{ self.vs_folder }\\",
+        }
+
+    def create_user_props(self, path: Path) -> None:
+        vc_targets_path = self.gaming_grdk_build_path / f"VS{ self.vs_version }/flatDeployment/MSBuild/Microsoft/VC/{ self.vs_toolset }"
+        vc_targets_path16 = self.gaming_grdk_build_path / f"VS2019/flatDeployment/MSBuild/Microsoft/VC/{ self.vs_toolset }"
+        vc_targets_path17 = self.gaming_grdk_build_path / f"VS2022/flatDeployment/MSBuild/Microsoft/VC/{ self.vs_toolset }"
+        additional_include_directories = ";".join(str(p) for p in self.gdk_include_paths)
+        additional_library_directories = ";".join(str(p) for p in self.gdk_library_paths)
+        durango_xdk_install_path = self.gdk_path / "Microsoft GDK"
+        with path.open("w") as f:
+            f.write(textwrap.dedent(f"""\
+                <?xml version="1.0" encoding="utf-8"?>
+                <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+                  <PropertyGroup>
+                    <VCTargetsPath>{ vc_targets_path }\\</VCTargetsPath>
+                    <VCTargetsPath16>{ vc_targets_path16 }\\</VCTargetsPath16>
+                    <VCTargetsPath17>{ vc_targets_path17 }\\</VCTargetsPath17>
+                    <BWOI_GDK_Path>{ self.gaming_grdk_build_path }\\</BWOI_GDK_Path>
+                    <Platform Condition="'$(Platform)' == ''">Gaming.Desktop.x64</Platform>
+                    <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+                    <XdkEditionTarget>{ self.gdk_edition }</XdkEditionTarget>
+                    <DurangoXdkInstallPath>{ durango_xdk_install_path }</DurangoXdkInstallPath>
+
+                    <DefaultXdkEditionRootVS2019>$(DurangoXdkInstallPath)\\{self.gdk_edition}\\GRDK\\VS2019\\flatDeployment\\MSBuild\\Microsoft\\VC\\{self.vs_toolset}\\Platforms\\$(Platform)\\</DefaultXdkEditionRootVS2019>
+                    <XdkEditionRootVS2019>$(DurangoXdkInstallPath)\\{self.gdk_edition}\\GRDK\\VS2019\\flatDeployment\\MSBuild\\Microsoft\\VC\\{self.vs_toolset}\\Platforms\\$(Platform)\\</XdkEditionRootVS2019>
+                    <DefaultXdkEditionRootVS2022>$(DurangoXdkInstallPath)\\{self.gdk_edition}\\GRDK\\VS2022\\flatDeployment\\MSBuild\\Microsoft\\VC\\{self.vs_toolset}\\Platforms\\$(Platform)\\</DefaultXdkEditionRootVS2022>
+                    <XdkEditionRootVS2022>$(DurangoXdkInstallPath)\\{self.gdk_edition}\\GRDK\\VS2022\\flatDeployment\\MSBuild\\Microsoft\\VC\\{self.vs_toolset}\\Platforms\\$(Platform)\\</XdkEditionRootVS2022>
+
+                    <Deterministic>true</Deterministic>
+                    <DisableInstalledVCTargetsUse>true</DisableInstalledVCTargetsUse>
+                    <ClearDevCommandPromptEnvVars>true</ClearDevCommandPromptEnvVars>
+                  </PropertyGroup>
+                  <ItemDefinitionGroup Condition="'$(Platform)' == 'Gaming.Desktop.x64'">
+                    <ClCompile>
+                      <AdditionalIncludeDirectories>{ additional_include_directories };%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+                    </ClCompile>
+                    <Link>
+                      <AdditionalLibraryDirectories>{ additional_library_directories };%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+                    </Link>
+                  </ItemDefinitionGroup>
+                </Project>
+            """))
+
+    @property
+    def gdk_include_paths(self) -> list[Path]:
+        return [
+            self.gaming_grdk_build_path / "gamekit/include",
+        ]
+
+    @property
+    def gdk_library_paths(self) -> list[Path]:
+        return [
+            self.gaming_grdk_build_path / f"gamekit/lib/{self.arch}",
+        ]
+
+    @property
+    def gdk_binary_path(self) -> list[Path]:
+        return [
+            self.gaming_grdk_build_path / "bin",
+            self.game_dk_path / "bin",
+        ]
+
+    @property
+    def build_env(self) -> dict[str, str]:
+        gdk_include = ";".join(str(p) for p in self.gdk_include_paths)
+        gdk_lib = ";".join(str(p) for p in self.gdk_library_paths)
+        gdk_path = ";".join(str(p) for p in self.gdk_binary_path)
+        return {
+            "GDK_INCLUDE": gdk_include,
+            "GDK_LIB": gdk_lib,
+            "GDK_PATH": gdk_path,
+        }
+
+    def print_env(self) -> None:
+        for k, v in self.env.items():
+            print(f"set \"{k}={v}\"")
+        print()
+        for k, v in self.build_env.items():
+            print(f"set \"{k}={v}\"")
+        print()
+        print(f"set \"PATH=%GDK_PATH%;%PATH%\"")
+        print(f"set \"LIB=%GDK_LIB%;%LIB%\"")
+        print(f"set \"INCLUDE=%GDK_INCLUDE%;%INCLUDE%\"")
+
+
+def main():
+    logging.basicConfig(level=logging.INFO)
+    parser = argparse.ArgumentParser(allow_abbrev=False)
+    parser.add_argument("--arch", choices=["amd64"], default="amd64", help="Architecture")
+    parser.add_argument("--download", action="store_true", help="Download GDK")
+    parser.add_argument("--extract", action="store_true", help="Extract downloaded GDK")
+    parser.add_argument("--copy-msbuild", action="store_true", help="Copy MSBuild files")
+    parser.add_argument("--temp-folder", help="Temporary folder where to download and extract GDK")
+    parser.add_argument("--gdk-path", required=True, type=Path, help="Folder where to store the GDK")
+    parser.add_argument("--ref-edition", type=str, help="Git ref and GDK edition separated by comma")
+    parser.add_argument("--vs-folder", required=True, type=Path, help="Installation folder of Visual Studio")
+    parser.add_argument("--vs-version", required=False, type=int, help="Visual Studio version")
+    parser.add_argument("--vs-toolset", required=False, help="Visual Studio toolset (e.g. v150)")
+    parser.add_argument("--props-folder", required=False, type=Path, default=Path(), help="Visual Studio toolset (e.g. v150)")
+    parser.add_argument("--no-user-props", required=False, dest="user_props", action="store_false", help="Don't ")
+    args = parser.parse_args()
+
+    logging.basicConfig(level=logging.INFO)
+
+    git_ref = None
+    gdk_edition = None
+    if args.ref_edition is not None:
+        git_ref, gdk_edition = args.ref_edition.split(",", 1)
+        try:
+            int(gdk_edition)
+        except ValueError:
+            parser.error("Edition should be an integer (YYMMUU) (Y=year M=month U=update)")
+
+    configurator = GdDesktopConfigurator(
+        arch=args.arch,
+        git_ref=git_ref,
+        gdk_edition=gdk_edition,
+        vs_folder=args.vs_folder,
+        vs_version=args.vs_version,
+        vs_toolset=args.vs_toolset,
+        gdk_path=args.gdk_path,
+        temp_folder=args.temp_folder,
+    )
+
+    if args.download:
+        configurator.download_archive()
+
+    if args.extract:
+        configurator.extract_zip_archive()
+
+        configurator.extract_development_kit()
+
+    if args.copy_msbuild:
+        configurator.copy_msbuild()
+
+    if args.user_props:
+        configurator.print_env()
+        configurator.create_user_props(args.props_folder / "Directory.Build.props")
+
+if __name__ == "__main__":
+    raise SystemExit(main())

+ 2 - 2
Engine/lib/sdl/build-scripts/showrev.sh

@@ -5,8 +5,8 @@
 SDL_ROOT=$(dirname $0)/..
 SDL_ROOT=$(dirname $0)/..
 cd $SDL_ROOT
 cd $SDL_ROOT
 
 
-if [ -e ./VERSION.txt ]; then
-    cat ./VERSION.txt
+if [ -e ./REVISION.txt ]; then
+    cat ./REVISION.txt
     exit 0
     exit 0
 fi
 fi
 
 

+ 10 - 2
Engine/lib/sdl/build-scripts/update-copyright.sh

@@ -1,7 +1,15 @@
 #!/bin/sh
 #!/bin/sh
 
 
-find . -type f -exec grep -Il "Copyright" {} \; \
+if [ "$SED" = "" ]; then
+    if type gsed >/dev/null; then
+        SED=gsed
+    else
+        SED=sed
+    fi
+fi
+
+find . -type f \
 | grep -v \.git                                 \
 | grep -v \.git                                 \
 | while read file; do                           \
 | while read file; do                           \
-    LC_ALL=C sed -b -i "s/\(.*Copyright.*\)[0-9]\{4\}\( *Sam Lantinga\)/\1`date +%Y`\2/" "$file"; \
+    LC_ALL=C $SED -b -i "s/\(.*Copyright.*\)[0-9]\{4\}\( *Sam Lantinga\)/\1`date +%Y`\2/" "$file"; \
 done
 done

+ 1 - 1
Engine/lib/sdl/build-scripts/updaterev.sh

@@ -29,7 +29,7 @@ done
 rev=`sh showrev.sh 2>/dev/null`
 rev=`sh showrev.sh 2>/dev/null`
 if [ "$rev" != "" ]; then
 if [ "$rev" != "" ]; then
     if [ -n "$dist" ]; then
     if [ -n "$dist" ]; then
-        echo "$rev" > "$outdir/VERSION.txt"
+        echo "$rev" > "$outdir/REVISION.txt"
     fi
     fi
     echo "/* Generated by updaterev.sh, do not edit */" >"$header.new"
     echo "/* Generated by updaterev.sh, do not edit */" >"$header.new"
     if [ -n "$vendor" ]; then
     if [ -n "$vendor" ]; then

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