Browse Source

update sdl to release 2.0.22

AzaezelX 3 years ago
parent
commit
d4307ea413
100 changed files with 2060 additions and 837 deletions
  1. 131 109
      Engine/lib/sdl/CMakeLists.txt
  2. 1 0
      Engine/lib/sdl/Makefile.in
  3. 4 2
      Engine/lib/sdl/Makefile.os2
  4. 30 0
      Engine/lib/sdl/WhatsNew.txt
  5. 2 2
      Engine/lib/sdl/Xcode/SDL/Info-Framework.plist
  6. 44 2
      Engine/lib/sdl/Xcode/SDL/SDL.xcodeproj/project.pbxproj
  7. 0 41
      Engine/lib/sdl/build-scripts/os2-buildbot.sh
  8. 1 1
      Engine/lib/sdl/build-scripts/winrtbuild.ps1
  9. 4 2
      Engine/lib/sdl/cmake/sdlchecks.cmake
  10. 108 28
      Engine/lib/sdl/configure
  11. 21 23
      Engine/lib/sdl/configure.ac
  12. 29 13
      Engine/lib/sdl/docs/README-directfb.md
  13. 1 1
      Engine/lib/sdl/docs/README-visualc.md
  14. 3 0
      Engine/lib/sdl/docs/README-vita.md
  15. 50 37
      Engine/lib/sdl/docs/README-windows.md
  16. 4 6
      Engine/lib/sdl/include/SDL_blendmode.h
  17. 2 0
      Engine/lib/sdl/include/SDL_config.h.cmake
  18. 1 0
      Engine/lib/sdl/include/SDL_config.h.in
  19. 1 0
      Engine/lib/sdl/include/SDL_config_emscripten.h
  20. 1 0
      Engine/lib/sdl/include/SDL_config_windows.h
  21. 2 0
      Engine/lib/sdl/include/SDL_config_winrt.h
  22. 74 2
      Engine/lib/sdl/include/SDL_hints.h
  23. 1 0
      Engine/lib/sdl/include/SDL_metal.h
  24. 30 8
      Engine/lib/sdl/include/SDL_rect.h
  25. 13 0
      Engine/lib/sdl/include/SDL_render.h
  26. 15 2
      Engine/lib/sdl/include/SDL_stdinc.h
  27. 2 0
      Engine/lib/sdl/include/SDL_syswm.h
  28. 1 1
      Engine/lib/sdl/include/SDL_version.h
  29. 1 0
      Engine/lib/sdl/include/SDL_video.h
  30. 1 1
      Engine/lib/sdl/include/begin_code.h
  31. 2 0
      Engine/lib/sdl/src/SDL.c
  32. 5 0
      Engine/lib/sdl/src/SDL_hints.c
  33. 93 0
      Engine/lib/sdl/src/SDL_list.c
  34. 39 0
      Engine/lib/sdl/src/SDL_list.h
  35. 1 1
      Engine/lib/sdl/src/audio/SDL_audio.c
  36. 1 1
      Engine/lib/sdl/src/audio/SDL_audiocvt.c
  37. 1 1
      Engine/lib/sdl/src/audio/SDL_wave.c
  38. 8 8
      Engine/lib/sdl/src/audio/emscripten/SDL_emscriptenaudio.c
  39. 63 22
      Engine/lib/sdl/src/audio/vita/SDL_vitaaudio.c
  40. 2 2
      Engine/lib/sdl/src/audio/vita/SDL_vitaaudio.h
  41. 4 0
      Engine/lib/sdl/src/audio/wasapi/SDL_wasapi.c
  42. 4 4
      Engine/lib/sdl/src/core/linux/SDL_fcitx.c
  43. 1 1
      Engine/lib/sdl/src/core/linux/SDL_fcitx.h
  44. 8 3
      Engine/lib/sdl/src/core/linux/SDL_ibus.c
  45. 1 1
      Engine/lib/sdl/src/core/linux/SDL_ibus.h
  46. 3 3
      Engine/lib/sdl/src/core/linux/SDL_ime.c
  47. 1 1
      Engine/lib/sdl/src/core/linux/SDL_ime.h
  48. 73 46
      Engine/lib/sdl/src/core/windows/SDL_windows.c
  49. 9 0
      Engine/lib/sdl/src/core/windows/SDL_windows.h
  50. 1 0
      Engine/lib/sdl/src/dynapi/SDL_dynapi_overrides.h
  51. 1 0
      Engine/lib/sdl/src/dynapi/SDL_dynapi_procs.h
  52. 1 0
      Engine/lib/sdl/src/events/SDL_keyboard.c
  53. 72 33
      Engine/lib/sdl/src/events/SDL_mouse.c
  54. 8 0
      Engine/lib/sdl/src/events/SDL_mouse_c.h
  55. 5 0
      Engine/lib/sdl/src/events/SDL_touch.c
  56. 1 19
      Engine/lib/sdl/src/filesystem/windows/SDL_sysfilesystem.c
  57. 6 4
      Engine/lib/sdl/src/hidapi/SDL_hidapi.c
  58. 1 0
      Engine/lib/sdl/src/hidapi/libusb/hid.c
  59. 12 10
      Engine/lib/sdl/src/hidapi/mac/hid.c
  60. 2 1
      Engine/lib/sdl/src/joystick/SDL_gamecontrollerdb.h
  61. 9 4
      Engine/lib/sdl/src/joystick/SDL_joystick.c
  62. 9 2
      Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_ps5.c
  63. 1 1
      Engine/lib/sdl/src/joystick/hidapi/SDL_hidapijoystick.c
  64. 13 0
      Engine/lib/sdl/src/joystick/iphoneos/SDL_mfijoystick.m
  65. 88 31
      Engine/lib/sdl/src/joystick/linux/SDL_sysjoystick.c
  66. 14 10
      Engine/lib/sdl/src/joystick/windows/SDL_rawinputjoystick.c
  67. 38 25
      Engine/lib/sdl/src/joystick/windows/SDL_windows_gaming_input.c
  68. 71 0
      Engine/lib/sdl/src/locale/vita/SDL_syslocale.c
  69. 4 4
      Engine/lib/sdl/src/main/windows/version.rc
  70. 60 39
      Engine/lib/sdl/src/render/SDL_render.c
  71. 19 6
      Engine/lib/sdl/src/render/SDL_sysrender.h
  72. 35 9
      Engine/lib/sdl/src/render/direct3d/SDL_render_d3d.c
  73. 10 0
      Engine/lib/sdl/src/render/direct3d11/SDL_render_d3d11.c
  74. 25 3
      Engine/lib/sdl/src/render/opengl/SDL_render_gl.c
  75. 260 27
      Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm.c
  76. 70 6
      Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_memory.c
  77. 10 6
      Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_memory.h
  78. 82 70
      Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_tools.c
  79. 2 5
      Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_tools.h
  80. 10 3
      Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_types.h
  81. 2 0
      Engine/lib/sdl/src/test/SDL_test_common.c
  82. 5 5
      Engine/lib/sdl/src/thread/os2/SDL_sysmutex.c
  83. 11 2
      Engine/lib/sdl/src/timer/os2/SDL_systimer.c
  84. 6 0
      Engine/lib/sdl/src/video/SDL_bmp.c
  85. 3 4
      Engine/lib/sdl/src/video/SDL_egl.c
  86. 1 40
      Engine/lib/sdl/src/video/SDL_pixels.c
  87. 1 0
      Engine/lib/sdl/src/video/SDL_sysvideo.h
  88. 32 22
      Engine/lib/sdl/src/video/SDL_video.c
  89. 1 0
      Engine/lib/sdl/src/video/android/SDL_androidvideo.c
  90. 6 0
      Engine/lib/sdl/src/video/android/SDL_androidwindow.c
  91. 1 0
      Engine/lib/sdl/src/video/android/SDL_androidwindow.h
  92. 2 1
      Engine/lib/sdl/src/video/dummy/SDL_nullvideo.c
  93. 27 11
      Engine/lib/sdl/src/video/emscripten/SDL_emscriptenframebuffer.c
  94. 40 16
      Engine/lib/sdl/src/video/emscripten/SDL_emscriptenmouse.c
  95. 2 2
      Engine/lib/sdl/src/video/emscripten/SDL_emscriptenvideo.c
  96. 19 5
      Engine/lib/sdl/src/video/uikit/SDL_uikitmessagebox.m
  97. 1 1
      Engine/lib/sdl/src/video/vita/SDL_vitaframebuffer.c
  98. 47 18
      Engine/lib/sdl/src/video/vita/SDL_vitagl_pvr.c
  99. 4 5
      Engine/lib/sdl/src/video/vita/SDL_vitagl_pvr_c.h
  100. 12 12
      Engine/lib/sdl/src/video/vita/SDL_vitagles.c

+ 131 - 109
Engine/lib/sdl/CMakeLists.txt

@@ -66,12 +66,12 @@ include(${SDL2_SOURCE_DIR}/cmake/sdlchecks.cmake)
 # set SDL_BINARY_AGE and SDL_INTERFACE_AGE to 0.
 set(SDL_MAJOR_VERSION 2)
 set(SDL_MINOR_VERSION 0)
-set(SDL_MICRO_VERSION 21)
-set(SDL_INTERFACE_AGE 3)
-set(SDL_BINARY_AGE 21)
+set(SDL_MICRO_VERSION 22)
+set(SDL_INTERFACE_AGE 0)
+set(SDL_BINARY_AGE 22)
 set(SDL_VERSION "${SDL_MAJOR_VERSION}.${SDL_MINOR_VERSION}.${SDL_MICRO_VERSION}")
 # the following should match the versions in Xcode project file:
-set(DYLIB_CURRENT_VERSION 19.3.0)
+set(DYLIB_CURRENT_VERSION 23.0.0)
 set(DYLIB_COMPATIBILITY_VERSION 1.0.0)
 
 # Set defaults preventing destination file conflicts
@@ -372,6 +372,7 @@ endforeach()
 
 # Allow some projects to be built conditionally.
 set_option(SDL2_DISABLE_SDL2MAIN   "Disable building/installation of SDL2main" OFF)
+set_option(SDL2_DISABLE_INSTALL    "Disable installation of SDL2" OFF)
 set_option(SDL2_DISABLE_UNINSTALL  "Disable uninstallation of SDL2" OFF)
 
 option_string(SDL_ASSERTIONS "Enable internal sanity checks (auto/disabled/release/enabled/paranoid)" "auto")
@@ -1600,6 +1601,7 @@ elseif(WINDOWS)
 
   # headers needed elsewhere
   check_include_file(tpcshrd.h HAVE_TPCSHRD_H)
+  check_include_file(roapi.h HAVE_ROAPI_H)
   check_include_file(mmdeviceapi.h HAVE_MMDEVICEAPI_H)
   check_include_file(audioclient.h HAVE_AUDIOCLIENT_H)
   check_include_file(sensorsapi.h HAVE_SENSORSAPI_H)
@@ -2279,6 +2281,11 @@ elseif(VITA)
       ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_systls.c)
     set(HAVE_SDL_THREADS TRUE)
   endif()
+  if(SDL_LOCALE)
+    file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/vita/*.c)
+    set(SOURCE_FILES ${SOURCE_FILES} ${LOCALE_SOURCES})
+    set(HAVE_SDL_LOCALE TRUE)
+  endif()
   if(SDL_TIMERS)
     set(SDL_TIMER_VITA 1)
     file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/vita/*.c)
@@ -2305,10 +2312,10 @@ elseif(VITA)
         list(APPEND EXTRA_LIBS
           pib
         )
-        set(HAVE_VITA_PIB ON)
+        set(HAVE_VIDEO_VITA_PIB ON)
         set(SDL_VIDEO_VITA_PIB 1)
       else()
-        set(HAVE_VITA_PIB OFF)
+        set(HAVE_VIDEO_VITA_PIB OFF)
       endif()
     endif()
 
@@ -2316,6 +2323,7 @@ elseif(VITA)
       check_include_file(gpu_es4/psp2_pvr_hint.h HAVE_PVR_H)
       if(HAVE_PVR_H)
         target_compile_definitions(sdl-build-options INTERFACE "-D__psp2__")
+        check_include_file(gl4esinit.h HAVE_GL4ES_H)
         set(SDL_VIDEO_OPENGL_EGL 1)
         set(HAVE_OPENGLES TRUE)
         set(SDL_VIDEO_OPENGL_ES 1)
@@ -2327,10 +2335,20 @@ elseif(VITA)
           libgpu_es4_ext_stub_weak
           libIMGEGL_stub_weak
         )
-        set(HAVE_VITA_PVR ON)
+
+        set(HAVE_VIDEO_VITA_PVR ON)
         set(SDL_VIDEO_VITA_PVR 1)
+
+        if(HAVE_GL4ES_H)
+          set(HAVE_OPENGL TRUE)
+          set(SDL_VIDEO_OPENGL 1)
+          set(SDL_VIDEO_RENDER_OGL 1)
+          list(APPEND EXTRA_LIBS libGL_stub)
+          set(SDL_VIDEO_VITA_PVR_OGL 1)
+        endif()
+
       else()
-        set(HAVE_VITA_PVR OFF)
+        set(HAVE_VIDEO_VITA_PVR OFF)
       endif()
     endif()
 
@@ -2342,6 +2360,7 @@ elseif(VITA)
       SceCtrl_stub
       SceAppMgr_stub
       SceAudio_stub
+      SceAudioIn_stub
       SceSysmodule_stub
       SceDisplay_stub
       SceCtrl_stub
@@ -2950,122 +2969,125 @@ if(SDL_TEST)
 endif()
 
 ##### Installation targets #####
-if(SDL_SHARED)
-  install(TARGETS SDL2 EXPORT SDL2Targets
-    LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
-    ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
-    RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
-endif()
-
-if(NOT WINDOWS_STORE AND NOT SDL2_DISABLE_SDL2MAIN)
-  install(TARGETS SDL2main EXPORT SDL2mainTargets
-    LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
-    ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
-    RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
-endif()
+if(NOT SDL2_DISABLE_INSTALL)
+  if(SDL_SHARED)
+    install(TARGETS SDL2 EXPORT SDL2Targets
+      LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+      ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+      RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
+  endif()
 
-if(SDL_STATIC)
-  install(TARGETS SDL2-static EXPORT SDL2staticTargets
-    LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
-    ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
-    RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
-endif()
+  if(NOT WINDOWS_STORE AND NOT SDL2_DISABLE_SDL2MAIN)
+    install(TARGETS SDL2main EXPORT SDL2mainTargets
+      LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+      ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+      RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
+  endif()
 
-##### Export files #####
-if (WINDOWS AND NOT MINGW)
-  set(PKG_PREFIX "cmake")
-else ()
-  set(PKG_PREFIX "${CMAKE_INSTALL_LIBDIR}/cmake/SDL2")
-endif ()
+  if(SDL_STATIC)
+    install(TARGETS SDL2-static EXPORT SDL2staticTargets
+      LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+      ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+      RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
+  endif()
+
+  ##### Export files #####
+  if (WINDOWS AND NOT MINGW)
+    set(PKG_PREFIX "cmake")
+  else ()
+    set(PKG_PREFIX "${CMAKE_INSTALL_LIBDIR}/cmake/SDL2")
+  endif ()
+
+  include(CMakePackageConfigHelpers)
+  write_basic_package_version_file("${CMAKE_BINARY_DIR}/SDL2ConfigVersion.cmake"
+    VERSION ${SDL_VERSION}
+    COMPATIBILITY AnyNewerVersion
+  )
 
-include(CMakePackageConfigHelpers)
-write_basic_package_version_file("${CMAKE_BINARY_DIR}/SDL2ConfigVersion.cmake"
-  VERSION ${SDL_VERSION}
-  COMPATIBILITY AnyNewerVersion
-)
+  if(SDL_SHARED)
+    install(EXPORT SDL2Targets
+      FILE SDL2Targets.cmake
+      NAMESPACE SDL2::
+      DESTINATION ${PKG_PREFIX}
+    )
+  endif()
 
-if(SDL_SHARED)
-  install(EXPORT SDL2Targets
-    FILE SDL2Targets.cmake
-    NAMESPACE SDL2::
-    DESTINATION ${PKG_PREFIX}
-  )
-endif()
+  if(NOT WINDOWS_STORE AND NOT SDL2_DISABLE_SDL2MAIN)
+    install(EXPORT SDL2mainTargets
+      FILE SDL2mainTargets.cmake
+      NAMESPACE SDL2::
+      DESTINATION ${PKG_PREFIX}
+    )
+  endif()
 
-if(NOT WINDOWS_STORE AND NOT SDL2_DISABLE_SDL2MAIN)
-  install(EXPORT SDL2mainTargets
-    FILE SDL2mainTargets.cmake
-    NAMESPACE SDL2::
-    DESTINATION ${PKG_PREFIX}
-  )
-endif()
+  if(SDL_STATIC)
+    install(EXPORT SDL2staticTargets
+      FILE SDL2staticTargets.cmake
+      NAMESPACE SDL2::
+      DESTINATION ${PKG_PREFIX}
+    )
+  endif()
 
-if(SDL_STATIC)
-  install(EXPORT SDL2staticTargets
-    FILE SDL2staticTargets.cmake
-    NAMESPACE SDL2::
+  install(
+    FILES
+      ${CMAKE_CURRENT_SOURCE_DIR}/SDL2Config.cmake
+      ${CMAKE_BINARY_DIR}/SDL2ConfigVersion.cmake
     DESTINATION ${PKG_PREFIX}
+    COMPONENT Devel
   )
-endif()
-
-install(
-  FILES
-    ${CMAKE_CURRENT_SOURCE_DIR}/SDL2Config.cmake
-    ${CMAKE_BINARY_DIR}/SDL2ConfigVersion.cmake
-  DESTINATION ${PKG_PREFIX}
-  COMPONENT Devel
-)
 
-file(GLOB INCLUDE_FILES ${SDL2_SOURCE_DIR}/include/*.h)
-file(GLOB BIN_INCLUDE_FILES ${SDL2_BINARY_DIR}/include/*.h)
-foreach(_FNAME ${BIN_INCLUDE_FILES})
-  get_filename_component(_INCNAME ${_FNAME} NAME)
-  list(REMOVE_ITEM INCLUDE_FILES ${SDL2_SOURCE_DIR}/include/${_INCNAME})
-endforeach()
-list(APPEND INCLUDE_FILES ${BIN_INCLUDE_FILES})
-install(FILES ${INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/SDL2)
-
-string(TOUPPER "${CMAKE_BUILD_TYPE}" UPPER_BUILD_TYPE)
-if (UPPER_BUILD_TYPE MATCHES DEBUG)
-  set(SOPOSTFIX "${SDL_CMAKE_DEBUG_POSTFIX}")
-else()
-  set(SOPOSTFIX "")
-endif()
-
-if(NOT (WINDOWS OR CYGWIN) OR MINGW)
-  if(SDL_SHARED)
-    set(SOEXT ${CMAKE_SHARED_LIBRARY_SUFFIX}) # ".so", ".dylib", etc.
-    get_target_property(SONAME SDL2 OUTPUT_NAME)
-    if(NOT ANDROID AND NOT MINGW AND NOT OS2)
-        install(CODE "
-          execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
-            \"lib${SONAME}${SOPOSTFIX}${SOEXT}\" \"libSDL2${SOPOSTFIX}${SOEXT}\"
-            WORKING_DIRECTORY \"${SDL2_BINARY_DIR}\")")
-        install(FILES ${SDL2_BINARY_DIR}/libSDL2${SOPOSTFIX}${SOEXT} DESTINATION "${CMAKE_INSTALL_LIBDIR}")
-    endif()
-  endif()
-  if(FREEBSD)
-    # FreeBSD uses ${PREFIX}/libdata/pkgconfig
-    install(FILES ${SDL2_BINARY_DIR}/sdl2.pc DESTINATION "libdata/pkgconfig")
+  file(GLOB INCLUDE_FILES ${SDL2_SOURCE_DIR}/include/*.h)
+  file(GLOB BIN_INCLUDE_FILES ${SDL2_BINARY_DIR}/include/*.h)
+  foreach(_FNAME ${BIN_INCLUDE_FILES})
+    get_filename_component(_INCNAME ${_FNAME} NAME)
+    list(REMOVE_ITEM INCLUDE_FILES ${SDL2_SOURCE_DIR}/include/${_INCNAME})
+  endforeach()
+  list(APPEND INCLUDE_FILES ${BIN_INCLUDE_FILES})
+  install(FILES ${INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/SDL2)
+
+  string(TOUPPER "${CMAKE_BUILD_TYPE}" UPPER_BUILD_TYPE)
+  if (UPPER_BUILD_TYPE MATCHES DEBUG)
+    set(SOPOSTFIX "${SDL_CMAKE_DEBUG_POSTFIX}")
   else()
-    install(FILES ${SDL2_BINARY_DIR}/sdl2.pc
-      DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
+    set(SOPOSTFIX "")
+  endif()
+
+  if(NOT (WINDOWS OR CYGWIN) OR MINGW)
+    if(SDL_SHARED)
+      set(SOEXT ${CMAKE_SHARED_LIBRARY_SUFFIX}) # ".so", ".dylib", etc.
+      get_target_property(SONAME SDL2 OUTPUT_NAME)
+      if(NOT ANDROID AND NOT MINGW AND NOT OS2)
+          install(CODE "
+            execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
+              \"lib${SONAME}${SOPOSTFIX}${SOEXT}\" \"libSDL2${SOPOSTFIX}${SOEXT}\"
+              WORKING_DIRECTORY \"${SDL2_BINARY_DIR}\")")
+          install(FILES ${SDL2_BINARY_DIR}/libSDL2${SOPOSTFIX}${SOEXT} DESTINATION "${CMAKE_INSTALL_LIBDIR}")
+      endif()
+    endif()
+    if(FREEBSD)
+      # FreeBSD uses ${PREFIX}/libdata/pkgconfig
+      install(FILES ${SDL2_BINARY_DIR}/sdl2.pc DESTINATION "libdata/pkgconfig")
+    else()
+      install(FILES ${SDL2_BINARY_DIR}/sdl2.pc
+        DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
+    endif()
+    install(PROGRAMS ${SDL2_BINARY_DIR}/sdl2-config DESTINATION "${CMAKE_INSTALL_BINDIR}")
+    # TODO: what about the .spec file? Is it only needed for RPM creation?
+    install(FILES "${SDL2_SOURCE_DIR}/sdl2.m4" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/aclocal")
   endif()
-  install(PROGRAMS ${SDL2_BINARY_DIR}/sdl2-config DESTINATION "${CMAKE_INSTALL_BINDIR}")
-  # TODO: what about the .spec file? Is it only needed for RPM creation?
-  install(FILES "${SDL2_SOURCE_DIR}/sdl2.m4" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/aclocal")
 endif()
 
 ##### Uninstall target #####
 
 if(NOT SDL2_DISABLE_UNINSTALL)
-if(NOT TARGET uninstall)
-  configure_file(
-      "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
-      "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
-      IMMEDIATE @ONLY)
+  if(NOT TARGET uninstall)
+    configure_file(
+        "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
+        "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
+        IMMEDIATE @ONLY)
 
-  add_custom_target(uninstall
-      COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
+    add_custom_target(uninstall
+        COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
+  endif()
 endif()
-endif(NOT SDL2_DISABLE_UNINSTALL)
+

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

@@ -19,6 +19,7 @@ distfile = $(distdir).tar.gz
 @SET_MAKE@
 SHELL	= @SHELL@
 CC      = @CC@
+CXX     = @CXX@
 INCLUDE = @INCLUDE@
 CFLAGS  = @BUILD_CFLAGS@
 EXTRA_CFLAGS = @EXTRA_CFLAGS@

+ 4 - 2
Engine/lib/sdl/Makefile.os2

@@ -11,7 +11,7 @@
 # wmake -f Makefile.os2 HIDAPI=1
 
 LIBNAME = SDL2
-VERSION = 2.0.21
+VERSION = 2.0.22
 DESCRIPTION = Simple DirectMedia Layer 2
 
 LIBICONV=0
@@ -60,7 +60,7 @@ CFLAGS_DLL+= -DHAVE_LIBUSB_H=1
 # building SDL itself (for DECLSPEC):
 CFLAGS_DLL+= -DBUILD_SDL
 
-SRCS = SDL.c SDL_assert.c SDL_error.c SDL_log.c SDL_dataqueue.c SDL_hints.c
+SRCS = SDL.c SDL_assert.c SDL_error.c SDL_log.c SDL_dataqueue.c SDL_hints.c SDL_list.c
 SRCS+= SDL_getenv.c SDL_iconv.c SDL_malloc.c SDL_qsort.c SDL_stdlib.c SDL_string.c SDL_strtokr.c SDL_crc32.c
 SRCS+= SDL_cpuinfo.c SDL_atomic.c SDL_spinlock.c SDL_thread.c SDL_timer.c
 SRCS+= SDL_rwops.c SDL_power.c
@@ -140,9 +140,11 @@ SDL_blendpoint.obj: SDL_blendpoint.c
     wcc386 $(CFLAGS_DLL) -wcd=200 -fo=$^@ $<
 SDL_RLEaccel.obj: SDL_RLEaccel.c
     wcc386 $(CFLAGS_DLL) -wcd=201 -fo=$^@ $<
+!ifeq HIDAPI 1
 # c99 mode needed because of structs with flexible array members in libusb.h
 SDL_hidapi.obj: SDL_hidapi.c
     wcc386 $(CFLAGS_DLL) -za99 -fo=$^@ $<
+!endif
 
 $(LIBICONV_LIB):  "src/core/os2/iconv2.lbc"
     @echo * Creating: $@

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

@@ -6,8 +6,38 @@ This is a list of major changes in SDL's version history.
 ---------------------------------------------------------------------------
 
 General:
+* Added SDL_RenderGetWindow() to get the window associated with a renderer
+* Added floating point rectangle functions:
+    * SDL_PointInFRect()
+    * SDL_FRectEmpty()
+    * SDL_FRectEquals()
+    * SDL_FRectEqualsEpsilon()
+    * SDL_HasIntersectionF()
+    * SDL_IntersectFRect()
+    * SDL_UnionFRect()
+    * SDL_EncloseFPoints()
+    * SDL_IntersectFRectAndLine()
+* Added SDL_IsTextInputShown() which returns whether the IME window is currently shown
+* Added SDL_ClearComposition() to dismiss the composition window without disabling IME input
+* Added SDL_TEXTEDITING_EXT event for handling long composition text, and a hint SDL_HINT_IME_SUPPORT_EXTENDED_TEXT to enable it
+* Added the hint SDL_HINT_MOUSE_RELATIVE_MODE_CENTER to control whether the mouse should be constrained to the whole window or the center of the window when relative mode is enabled
+* The mouse is now automatically captured when mouse buttons are pressed, and the hint SDL_HINT_MOUSE_AUTO_CAPTURE allows you to control this behavior
+* Added the hint SDL_HINT_VIDEO_FOREIGN_WINDOW_OPENGL to let SDL know that a foreign window will be used with OpenGL
+* Added the hint SDL_HINT_VIDEO_FOREIGN_WINDOW_VULKAN to let SDL know that a foreign window will be used with Vulkan
+* Added the hint SDL_HINT_QUIT_ON_LAST_WINDOW_CLOSE to specify whether an SDL_QUIT event will be delivered when the last application window is closed
 * Added the hint SDL_HINT_JOYSTICK_ROG_CHAKRAM to control whether ROG Chakram mice show up as joysticks
 
+Windows:
+* Added support for SDL_BLENDOPERATION_MINIMUM and SDL_BLENDOPERATION_MAXIMUM to the D3D9 renderer
+
+Linux:
+* Compiling with Wayland support requires libwayland-client version 1.18.0 or later
+* Added the hint SDL_HINT_X11_WINDOW_TYPE to specify the _NET_WM_WINDOW_TYPE of SDL windows
+* Added the hint SDL_HINT_VIDEO_WAYLAND_PREFER_LIBDECOR to allow using libdecor with compositors that support xdg-decoration
+
+Android:
+* Added SDL_AndroidSendMessage() to send a custom command to the SDL java activity
+
 
 ---------------------------------------------------------------------------
 2.0.20:

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

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

+ 44 - 2
Engine/lib/sdl/Xcode/SDL/SDL.xcodeproj/project.pbxproj

@@ -111,6 +111,24 @@
 		A1626A582617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; };
 		A1626A592617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; };
 		A1626A5A2617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; };
+		A1BB8B6327F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; };
+		A1BB8B6427F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; };
+		A1BB8B6527F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; };
+		A1BB8B6627F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; };
+		A1BB8B6727F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; };
+		A1BB8B6827F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; };
+		A1BB8B6927F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; };
+		A1BB8B6A27F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; };
+		A1BB8B6B27F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; };
+		A1BB8B6C27F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; };
+		A1BB8B6D27F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; };
+		A1BB8B6E27F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; };
+		A1BB8B6F27F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; };
+		A1BB8B7027F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; };
+		A1BB8B7127F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; };
+		A1BB8B7227F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; };
+		A1BB8B7327F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; };
+		A1BB8B7427F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; };
 		A7381E961D8B69D600B177DD /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E951D8B69D600B177DD /* CoreAudio.framework */; };
 		A7381E971D8B6A0300B177DD /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E931D8B69C300B177DD /* AudioToolbox.framework */; };
 		A75FCCFD23E25AB700529352 /* SDL_shaders_metal_tvos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E323E2514000DCD162 /* SDL_shaders_metal_tvos.h */; };
@@ -3574,6 +3592,8 @@
 		75E09159241EA924004729E1 /* SDL_virtualjoystick_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_virtualjoystick_c.h; sourceTree = "<group>"; };
 		A1626A3D2617006A003F1973 /* SDL_triangle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_triangle.c; sourceTree = "<group>"; };
 		A1626A512617008C003F1973 /* SDL_triangle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_triangle.h; sourceTree = "<group>"; };
+		A1BB8B6127F6CF320057CFA8 /* SDL_list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_list.c; sourceTree = "<group>"; };
+		A1BB8B6227F6CF330057CFA8 /* SDL_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_list.h; sourceTree = "<group>"; };
 		A7381E931D8B69C300B177DD /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
 		A7381E951D8B69D600B177DD /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
 		A75FCEB323E25AB700529352 /* libSDL2.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libSDL2.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -4304,6 +4324,8 @@
 				A7D8A5AB23E2513D00DCD162 /* SDL_hints.c */,
 				A7D8A58323E2513D00DCD162 /* SDL_internal.h */,
 				A7D8A5DD23E2513D00DCD162 /* SDL_log.c */,
+				A1BB8B6127F6CF320057CFA8 /* SDL_list.c */,
+				A1BB8B6227F6CF330057CFA8 /* SDL_list.h */,
 				A7D8A57123E2513D00DCD162 /* SDL.c */,
 			);
 			name = "Library Source";
@@ -5284,6 +5306,7 @@
 				A75FCD4523E25AB700529352 /* SDL_gesture_c.h in Headers */,
 				A75FCD4623E25AB700529352 /* SDL_shaders_gl.h in Headers */,
 				A75FCD4723E25AB700529352 /* SDL_systhread_c.h in Headers */,
+				A1BB8B7327F6CF330057CFA8 /* SDL_list.h in Headers */,
 				A75FCD4823E25AB700529352 /* SDL_keycode.h in Headers */,
 				5616CA63252BB35F005D5928 /* SDL_sysurl.h in Headers */,
 				A75FCD4A23E25AB700529352 /* SDL_cocoakeyboard.h in Headers */,
@@ -5509,6 +5532,7 @@
 				A75FCEFE23E25AC700529352 /* SDL_gesture_c.h in Headers */,
 				A75FCEFF23E25AC700529352 /* SDL_shaders_gl.h in Headers */,
 				A75FCF0023E25AC700529352 /* SDL_systhread_c.h in Headers */,
+				A1BB8B7427F6CF330057CFA8 /* SDL_list.h in Headers */,
 				A75FCF0123E25AC700529352 /* SDL_keycode.h in Headers */,
 				5616CA66252BB361005D5928 /* SDL_sysurl.h in Headers */,
 				A75FCF0323E25AC700529352 /* SDL_cocoakeyboard.h in Headers */,
@@ -5707,6 +5731,7 @@
 				A769B0C623E259AE00872273 /* SDL_windowevents_c.h in Headers */,
 				A769B0C823E259AE00872273 /* SDL_cocoavideo.h in Headers */,
 				5605721C2473688D00B46B66 /* SDL_syslocale.h in Headers */,
+				A1BB8B7127F6CF330057CFA8 /* SDL_list.h in Headers */,
 				A769B0CA23E259AE00872273 /* SDL_uikitevents.h in Headers */,
 				A769B0CB23E259AE00872273 /* SDL_gesture_c.h in Headers */,
 				A769B0CC23E259AE00872273 /* SDL_shaders_gl.h in Headers */,
@@ -5955,6 +5980,7 @@
 				A7D8A98E23E2514000DCD162 /* SDL_sensor_c.h in Headers */,
 				A7D8BA7423E2514400DCD162 /* SDL_shaders_gl.h in Headers */,
 				A7D8BA5023E2514400DCD162 /* SDL_shaders_gles2.h in Headers */,
+				A1BB8B6D27F6CF330057CFA8 /* SDL_list.h in Headers */,
 				A7D8B98D23E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */,
 				A7D8B99C23E2514400DCD162 /* SDL_shaders_metal_osx.h in Headers */,
 				A7D8B9A223E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */,
@@ -6185,6 +6211,7 @@
 				A7D8A98F23E2514000DCD162 /* SDL_sensor_c.h in Headers */,
 				A7D8BA7523E2514400DCD162 /* SDL_shaders_gl.h in Headers */,
 				A7D8BA5123E2514400DCD162 /* SDL_shaders_gles2.h in Headers */,
+				A1BB8B6E27F6CF330057CFA8 /* SDL_list.h in Headers */,
 				A7D8B98E23E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */,
 				A7D8B99D23E2514400DCD162 /* SDL_shaders_metal_osx.h in Headers */,
 				A7D8B9A323E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */,
@@ -6332,6 +6359,7 @@
 				A7D8BBAF23E2514500DCD162 /* SDL_windowevents_c.h in Headers */,
 				A7D8AF0423E2514100DCD162 /* SDL_cocoavideo.h in Headers */,
 				5605721A2473688C00B46B66 /* SDL_syslocale.h in Headers */,
+				A1BB8B7027F6CF330057CFA8 /* SDL_list.h in Headers */,
 				A7D8ACC123E2514100DCD162 /* SDL_uikitevents.h in Headers */,
 				A7D8BB3D23E2514500DCD162 /* SDL_gesture_c.h in Headers */,
 				A7D8BA7723E2514400DCD162 /* SDL_shaders_gl.h in Headers */,
@@ -6580,6 +6608,7 @@
 				A7D8A98D23E2514000DCD162 /* SDL_sensor_c.h in Headers */,
 				A7D8BA7323E2514400DCD162 /* SDL_shaders_gl.h in Headers */,
 				A7D8BA4F23E2514400DCD162 /* SDL_shaders_gles2.h in Headers */,
+				A1BB8B6C27F6CF330057CFA8 /* SDL_list.h in Headers */,
 				A7D8B98C23E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */,
 				A7D8B99B23E2514400DCD162 /* SDL_shaders_metal_osx.h in Headers */,
 				A7D8B9A123E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */,
@@ -6796,6 +6825,7 @@
 				A7D8B29F23E2514200DCD162 /* vulkan_xlib.h in Headers */,
 				A7D8B25D23E2514200DCD162 /* vulkan_vi.h in Headers */,
 				A7D8B29923E2514200DCD162 /* vulkan_mir.h in Headers */,
+				A1BB8B6F27F6CF330057CFA8 /* SDL_list.h in Headers */,
 				A7D8BB4E23E2514500DCD162 /* default_cursor.h in Headers */,
 				A7D8B9FE23E2514400DCD162 /* SDL_render_sw_c.h in Headers */,
 				A7D8BBED23E2574800DCD162 /* SDL_uikitappdelegate.h in Headers */,
@@ -6918,6 +6948,7 @@
 				A7D8BB3E23E2514500DCD162 /* SDL_gesture_c.h in Headers */,
 				A7D8BA7823E2514400DCD162 /* SDL_shaders_gl.h in Headers */,
 				A7D8B42D23E2514300DCD162 /* SDL_systhread_c.h in Headers */,
+				A1BB8B7227F6CF330057CFA8 /* SDL_list.h in Headers */,
 				DB313FDB17554B71006C0E22 /* SDL_keycode.h in Headers */,
 				A7D8AE9323E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */,
 				A7D8ACE623E2514100DCD162 /* SDL_uikitvulkan.h in Headers */,
@@ -7554,6 +7585,7 @@
 				A75FCE8423E25AB700529352 /* e_exp.c in Sources */,
 				A75FCE8523E25AB700529352 /* SDL_quit.c in Sources */,
 				A75FCE8623E25AB700529352 /* SDL_cocoawindow.m in Sources */,
+				A1BB8B6A27F6CF330057CFA8 /* SDL_list.c in Sources */,
 				A75FCE8723E25AB700529352 /* SDL_sysmutex.c in Sources */,
 				A75FCE8823E25AB700529352 /* SDL_syshaptic.c in Sources */,
 				F3F07D61269640160074468B /* SDL_hidapi_luna.c in Sources */,
@@ -7741,6 +7773,7 @@
 				A75FD03D23E25AC700529352 /* e_exp.c in Sources */,
 				A75FD03E23E25AC700529352 /* SDL_quit.c in Sources */,
 				A75FD03F23E25AC700529352 /* SDL_cocoawindow.m in Sources */,
+				A1BB8B6B27F6CF330057CFA8 /* SDL_list.c in Sources */,
 				A75FD04023E25AC700529352 /* SDL_sysmutex.c in Sources */,
 				A75FD04123E25AC700529352 /* SDL_syshaptic.c in Sources */,
 				F3F07D62269640160074468B /* SDL_hidapi_luna.c in Sources */,
@@ -7927,6 +7960,7 @@
 				A769B20F23E259AE00872273 /* SDL_syshaptic.c in Sources */,
 				A769B21023E259AE00872273 /* e_exp.c in Sources */,
 				F395C1A12569C68F00942BFF /* SDL_iokitjoystick.c in Sources */,
+				A1BB8B6827F6CF330057CFA8 /* SDL_list.c in Sources */,
 				A769B21123E259AE00872273 /* SDL_quit.c in Sources */,
 				A769B21223E259AE00872273 /* SDL_cocoawindow.m in Sources */,
 				A769B21323E259AE00872273 /* SDL_sysmutex.c in Sources */,
@@ -8116,6 +8150,7 @@
 				A7D8B43B23E2514300DCD162 /* SDL_sysmutex.c in Sources */,
 				A7D8AAB123E2514100DCD162 /* SDL_syshaptic.c in Sources */,
 				A7D8B5CA23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */,
+				A1BB8B6427F6CF330057CFA8 /* SDL_list.c in Sources */,
 				A7D8AC1023E2514100DCD162 /* SDL_video.c in Sources */,
 				560572062473687700B46B66 /* SDL_syslocale.m in Sources */,
 				F3F07D5B269640160074468B /* SDL_hidapi_luna.c in Sources */,
@@ -8303,6 +8338,7 @@
 				A7D8B43C23E2514300DCD162 /* SDL_sysmutex.c in Sources */,
 				A7D8AAB223E2514100DCD162 /* SDL_syshaptic.c in Sources */,
 				A7D8B5CB23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */,
+				A1BB8B6527F6CF330057CFA8 /* SDL_list.c in Sources */,
 				A7D8AC1123E2514100DCD162 /* SDL_video.c in Sources */,
 				560572072473687800B46B66 /* SDL_syslocale.m in Sources */,
 				F3F07D5C269640160074468B /* SDL_hidapi_luna.c in Sources */,
@@ -8489,6 +8525,7 @@
 				A7D8AADE23E2514100DCD162 /* SDL_syshaptic.c in Sources */,
 				A7D8BAE923E2514500DCD162 /* e_exp.c in Sources */,
 				F395C1A02569C68F00942BFF /* SDL_iokitjoystick.c in Sources */,
+				A1BB8B6727F6CF330057CFA8 /* SDL_list.c in Sources */,
 				A7D8BB8523E2514500DCD162 /* SDL_quit.c in Sources */,
 				A7D8AEAA23E2514100DCD162 /* SDL_cocoawindow.m in Sources */,
 				A7D8B43E23E2514300DCD162 /* SDL_sysmutex.c in Sources */,
@@ -8665,6 +8702,7 @@
 				A7D8B55123E2514300DCD162 /* SDL_hidapi_switch.c in Sources */,
 				A7D8B96223E2514400DCD162 /* SDL_strtokr.c in Sources */,
 				A7D8BB7523E2514500DCD162 /* SDL_clipboardevents.c in Sources */,
+				A1BB8B6327F6CF330057CFA8 /* SDL_list.c in Sources */,
 				A7D8BAB523E2514400DCD162 /* k_cos.c in Sources */,
 				A7D8B54523E2514300DCD162 /* SDL_hidapijoystick.c in Sources */,
 				A7D8B97423E2514400DCD162 /* SDL_malloc.c in Sources */,
@@ -8850,6 +8888,7 @@
 				A7D8B96523E2514400DCD162 /* SDL_strtokr.c in Sources */,
 				A7D8BB7823E2514500DCD162 /* SDL_clipboardevents.c in Sources */,
 				A7D8BAB823E2514400DCD162 /* k_cos.c in Sources */,
+				A1BB8B6627F6CF330057CFA8 /* SDL_list.c in Sources */,
 				A7D8B54823E2514300DCD162 /* SDL_hidapijoystick.c in Sources */,
 				A7D8B97723E2514400DCD162 /* SDL_malloc.c in Sources */,
 				A7D8BBF023E2574800DCD162 /* SDL_uikitclipboard.m in Sources */,
@@ -9035,6 +9074,7 @@
 				A7D8B96723E2514400DCD162 /* SDL_strtokr.c in Sources */,
 				A7D8BB7A23E2514500DCD162 /* SDL_clipboardevents.c in Sources */,
 				A7D8BABA23E2514400DCD162 /* k_cos.c in Sources */,
+				A1BB8B6927F6CF330057CFA8 /* SDL_list.c in Sources */,
 				A7D8B54A23E2514300DCD162 /* SDL_hidapijoystick.c in Sources */,
 				A7D8B97923E2514400DCD162 /* SDL_malloc.c in Sources */,
 				A7D8B8CB23E2514400DCD162 /* SDL_audio.c in Sources */,
@@ -9111,7 +9151,7 @@
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				DEPLOYMENT_POSTPROCESSING = YES;
 				DYLIB_COMPATIBILITY_VERSION = 1.0.0;
-				DYLIB_CURRENT_VERSION = 19.3.0;
+				DYLIB_CURRENT_VERSION = 23.0.0;
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				GCC_ALTIVEC_EXTENSIONS = YES;
@@ -9195,7 +9235,7 @@
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				DYLIB_COMPATIBILITY_VERSION = 1.0.0;
-				DYLIB_CURRENT_VERSION = 19.3.0;
+				DYLIB_CURRENT_VERSION = 23.0.0;
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				ENABLE_TESTABILITY = YES;
@@ -9387,6 +9427,7 @@
 			buildSettings = {
 				CLANG_ENABLE_OBJC_ARC = YES;
 				CLANG_LINK_OBJC_RUNTIME = NO;
+				GCC_PREPROCESSOR_DEFINITIONS = GLES_SILENCE_DEPRECATION;
 				GCC_SYMBOLS_PRIVATE_EXTERN = YES;
 				SKIP_INSTALL = YES;
 				SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
@@ -9398,6 +9439,7 @@
 			buildSettings = {
 				CLANG_ENABLE_OBJC_ARC = YES;
 				CLANG_LINK_OBJC_RUNTIME = NO;
+				GCC_PREPROCESSOR_DEFINITIONS = GLES_SILENCE_DEPRECATION;
 				GCC_SYMBOLS_PRIVATE_EXTERN = YES;
 				SKIP_INSTALL = YES;
 				SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";

+ 0 - 41
Engine/lib/sdl/build-scripts/os2-buildbot.sh

@@ -1,41 +0,0 @@
-#!/bin/bash
-
-# This is the script buildbot.libsdl.org uses to cross-compile SDL2 from
-#  x86 Linux to OS/2, using OpenWatcom.
-
-# The final zipfile can be unpacked on any machine that supports OpenWatcom
-#  (Windows, Linux, OS/2, etc). Point the compiler at the include directory
-#  and link against the SDL2.lib file. Ship the SDL2.dll with your app.
-
-if [ -z "$WATCOM" ]; then
-    echo "This script expects \$WATCOM to be set to the OpenWatcom install dir." 1>&2
-    echo "This is often something like '/usr/local/share/watcom'" 1>&2
-    exit 1
-fi
-export PATH="$WATCOM/binl64:$PATH"
-
-ZIPFILE="$1"
-if [ -z $1 ]; then
-    ZIPFILE=sdl-os2.zip
-fi
-ZIPDIR=buildbot/SDL
-
-set -e
-set -x
-
-cd `dirname "$0"`
-cd ..
-
-rm -f $ZIPFILE
-wmake -f Makefile.os2
-rm -rf $ZIPDIR
-mkdir -p $ZIPDIR
-chmod 644 SDL2.dll SDL2.lib SDL2test.lib
-mv SDL2.dll SDL2.lib SDL2test.lib $ZIPDIR/
-cp -R include $ZIPDIR/
-zip -9r "buildbot/$ZIPFILE" $ZIPDIR
-
-wmake -f Makefile.os2 distclean
-
-set +x
-echo "All done. Final installable is in $ZIPFILE ...";

+ 1 - 1
Engine/lib/sdl/build-scripts/winrtbuild.ps1

@@ -39,7 +39,7 @@
 #
 
 # Base version of SDL, used for packaging purposes
-$SDLVersion = "2.0.21"
+$SDLVersion = "2.0.22"
 
 # Gets the .bat file that sets up an MSBuild environment, given one of
 # Visual Studio's, "PlatformToolset"s.

+ 4 - 2
Engine/lib/sdl/cmake/sdlchecks.cmake

@@ -632,7 +632,7 @@ endmacro()
 # - HAVE_SDL_LOADSO opt
 macro(CheckWayland)
   if(SDL_WAYLAND)
-    pkg_check_modules(WAYLAND wayland-client wayland-egl wayland-cursor egl "xkbcommon>=0.5.0")
+    pkg_check_modules(WAYLAND "wayland-client>=1.18" wayland-egl wayland-cursor egl "xkbcommon>=0.5.0")
 
     if(WAYLAND_FOUND)
       find_program(WAYLAND_SCANNER NAMES wayland-scanner REQUIRED)
@@ -792,7 +792,9 @@ macro(CheckVivante)
       set(SDL_VIDEO_DRIVER_VIVANTE 1)
       if(HAVE_VIVANTE_VDK)
         set(SDL_VIDEO_DRIVER_VIVANTE_VDK 1)
-        list(APPEND EXTRA_LIBS VDK VIVANTE)
+        find_library(VIVANTE_LIBRARY REQUIRED NAMES VIVANTE vivante drm_vivante)
+        find_library(VIVANTE_VDK_LIBRARY VDK REQUIRED)
+        list(APPEND EXTRA_LIBS ${VIVANTE_LIBRARY} ${VIVANTE_VDK_LIBRARY})
       else()
         set(SDL_CFLAGS "${SDL_CFLAGS} -DLINUX -DEGL_API_FB")
         list(APPEND EXTRA_LIBS EGL)

+ 108 - 28
Engine/lib/sdl/configure

@@ -673,6 +673,8 @@ X_CFLAGS
 XMKMF
 RPI_LIBS
 RPI_CFLAGS
+DECOR_LIBS
+DECOR_CFLAGS
 FUSIONSOUND_LIBS
 FUSIONSOUND_CFLAGS
 ARTSCONFIG
@@ -944,6 +946,8 @@ PULSEAUDIO_CFLAGS
 PULSEAUDIO_LIBS
 FUSIONSOUND_CFLAGS
 FUSIONSOUND_LIBS
+DECOR_CFLAGS
+DECOR_LIBS
 RPI_CFLAGS
 RPI_LIBS
 XMKMF
@@ -1779,6 +1783,9 @@ Some influential environment variables:
               C compiler flags for FUSIONSOUND, overriding pkg-config
   FUSIONSOUND_LIBS
               linker flags for FUSIONSOUND, overriding pkg-config
+  DECOR_CFLAGS
+              C compiler flags for DECOR, overriding pkg-config
+  DECOR_LIBS  linker flags for DECOR, overriding pkg-config
   RPI_CFLAGS  C compiler flags for RPI, overriding pkg-config
   RPI_LIBS    linker flags for RPI, overriding pkg-config
   XMKMF       Path to xmkmf, Makefile generator for X Window System
@@ -2859,9 +2866,9 @@ orig_CFLAGS="$CFLAGS"
 #
 SDL_MAJOR_VERSION=2
 SDL_MINOR_VERSION=0
-SDL_MICRO_VERSION=21
-SDL_INTERFACE_AGE=3
-SDL_BINARY_AGE=21
+SDL_MICRO_VERSION=22
+SDL_INTERFACE_AGE=0
+SDL_BINARY_AGE=22
 SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION
 
 
@@ -20572,7 +20579,7 @@ $as_echo_n "checking for Wayland support... " >&6; }
         video_wayland=no
         if  test x$video_opengl_egl = xyes && \
             test x$video_opengles_v2 = xyes; then
-            if $PKG_CONFIG --exists wayland-client wayland-scanner wayland-egl wayland-cursor egl 'xkbcommon >= 0.5.0'; then
+            if $PKG_CONFIG --exists 'wayland-client >= 1.18' wayland-scanner wayland-egl wayland-cursor egl 'xkbcommon >= 0.5.0'; then
                 WAYLAND_CFLAGS=`$PKG_CONFIG --cflags wayland-client wayland-egl wayland-cursor xkbcommon`
                 WAYLAND_LIBS=`$PKG_CONFIG --libs wayland-client wayland-egl wayland-cursor xkbcommon`
                 WAYLAND_SCANNER=`$PKG_CONFIG --variable=wayland_scanner wayland-scanner`
@@ -20676,17 +20683,79 @@ else
 fi
 
             if test x$enable_libdecor = xyes; then
-                { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libdecor support" >&5
-$as_echo_n "checking for libdecor support... " >&6; }
-                if $PKG_CONFIG --exists libdecor-0; then :
-  video_libdecor=yes
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libdecor-0" >&5
+$as_echo_n "checking for libdecor-0... " >&6; }
+
+if test -n "$DECOR_CFLAGS"; then
+    pkg_cv_DECOR_CFLAGS="$DECOR_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdecor-0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libdecor-0") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_DECOR_CFLAGS=`$PKG_CONFIG --cflags "libdecor-0" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$DECOR_LIBS"; then
+    pkg_cv_DECOR_LIBS="$DECOR_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdecor-0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libdecor-0") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_DECOR_LIBS=`$PKG_CONFIG --libs "libdecor-0" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        DECOR_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libdecor-0" 2>&1`
+        else
+	        DECOR_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libdecor-0" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$DECOR_PKG_ERRORS" >&5
+
+	video_libdecor=no
+elif test $pkg_failed = untried; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	video_libdecor=no
 else
-  video_libdecor=no
+	DECOR_CFLAGS=$pkg_cv_DECOR_CFLAGS
+	DECOR_LIBS=$pkg_cv_DECOR_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	video_libdecor=yes
 fi
-                { $as_echo "$as_me:${as_lineno-$LINENO}: result: $video_libdecor" >&5
-$as_echo "$video_libdecor" >&6; }
                 if test x$video_libdecor = xyes; then
-                    EXTRA_CFLAGS="$EXTRA_CFLAGS `$PKG_CONFIG --cflags libdecor-0`"
+                    EXTRA_CFLAGS="$EXTRA_CFLAGS $DECOR_CFLAGS"
 
 $as_echo "#define HAVE_LIBDECOR_H 1" >>confdefs.h
 
@@ -20699,18 +20768,16 @@ else
 fi
 
 
+                    decor_lib=`find_lib "libdecor-0.so.*" "$DECOR_LIBS" | sed 's/.*\/\(.*\)/\1/; q'`
+
                     if test x$enable_wayland_shared != xyes; then
                        enable_libdecor_shared=no
                     fi
-
-                    decor_lib=`find_lib "libdecor-0.so.*" "" | sed 's/.*\/\(.*\)/\1/; q'`
-
                     if test x$have_loadso != xyes && \
                        test x$enable_libdecor_shared = xyes; then
                         { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic libdecor loading" >&5
 $as_echo "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic libdecor loading" >&2;}
                     fi
-
                     if test x$have_loadso = xyes && \
                        test x$enable_libdecor_shared = xyes && test x$decor_lib != x; then
                         echo "-- dynamic libdecor -> $decor_lib"
@@ -20720,7 +20787,7 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
                     else
-                        EXTRA_LDFLAGS="$EXTRA_LDFLAGS `$PKG_CONFIG --libs libdecor-0`"
+                        EXTRA_LDFLAGS="$EXTRA_LDFLAGS $DECOR_LIBS"
                     fi
                 fi
             fi
@@ -24712,6 +24779,30 @@ $as_echo "$have_wince" >&6; }
 
     # This fixes Windows stack alignment with newer GCC
     CheckStackBoundary
+
+    # headers needed elsewhere
+    ac_fn_c_check_header_mongrel "$LINENO" "tpcshrd.h" "ac_cv_header_tpcshrd_h" "$ac_includes_default"
+if test "x$ac_cv_header_tpcshrd_h" = xyes; then :
+  have_tpcshrd_h=yes
+fi
+
+
+    if test x$have_tpcshrd_h = xyes; then
+
+$as_echo "#define HAVE_TPCSHRD_H 1" >>confdefs.h
+
+    fi
+    ac_fn_c_check_header_mongrel "$LINENO" "roapi.h" "ac_cv_header_roapi_h" "$ac_includes_default"
+if test "x$ac_cv_header_roapi_h" = xyes; then :
+  have_roapi_h=yes
+fi
+
+
+    if test x$have_roapi_h = xyes; then
+
+$as_echo "#define HAVE_ROAPI_H 1" >>confdefs.h
+
+    fi
 }
 
 CheckOS2()
@@ -26188,17 +26279,6 @@ $as_echo "#define SDL_HAPTIC_DINPUT 1" >>confdefs.h
                 have_haptic=yes
             fi
         fi
-        ac_fn_c_check_header_mongrel "$LINENO" "tpcshrd.h" "ac_cv_header_tpcshrd_h" "$ac_includes_default"
-if test "x$ac_cv_header_tpcshrd_h" = xyes; then :
-  have_tpcshrd_h=yes
-fi
-
-
-        if test x$have_tpcshrd_h = xyes; then
-
-$as_echo "#define HAVE_TPCSHRD_H 1" >>confdefs.h
-
-        fi
         # Set up files for the sensor library
         ac_fn_c_check_header_mongrel "$LINENO" "sensorsapi.h" "ac_cv_header_sensorsapi_h" "$ac_includes_default"
 if test "x$ac_cv_header_sensorsapi_h" = xyes; then :

+ 21 - 23
Engine/lib/sdl/configure.ac

@@ -22,9 +22,9 @@ dnl Set various version strings - taken gratefully from the GTk sources
 #
 SDL_MAJOR_VERSION=2
 SDL_MINOR_VERSION=0
-SDL_MICRO_VERSION=21
-SDL_INTERFACE_AGE=3
-SDL_BINARY_AGE=21
+SDL_MICRO_VERSION=22
+SDL_INTERFACE_AGE=0
+SDL_BINARY_AGE=22
 SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION
 
 AC_SUBST(SDL_MAJOR_VERSION)
@@ -1555,7 +1555,7 @@ CheckWayland()
         video_wayland=no
         if  test x$video_opengl_egl = xyes && \
             test x$video_opengles_v2 = xyes; then
-            if $PKG_CONFIG --exists wayland-client wayland-scanner wayland-egl wayland-cursor egl 'xkbcommon >= 0.5.0'; then
+            if $PKG_CONFIG --exists 'wayland-client >= 1.18' wayland-scanner wayland-egl wayland-cursor egl 'xkbcommon >= 0.5.0'; then
                 WAYLAND_CFLAGS=`$PKG_CONFIG --cflags wayland-client wayland-egl wayland-cursor xkbcommon`
                 WAYLAND_LIBS=`$PKG_CONFIG --libs wayland-client wayland-egl wayland-cursor xkbcommon`
                 WAYLAND_SCANNER=`$PKG_CONFIG --variable=wayland_scanner wayland-scanner`
@@ -1626,39 +1626,31 @@ dnl FIXME: Do BSD and OS X need special cases?
 
 dnl See if libdecor is available
             AC_ARG_ENABLE(libdecor,
-[AS_HELP_STRING([--enable-libdecor], [use libdecor for Wayland client-side decorations [default=yes]])],
-                          , enable_libdecor=yes)
+[AS_HELP_STRING([--enable-libdecor], [use libdecor for Wayland client-side decorations [default=yes]])],, enable_libdecor=yes)
             if test x$enable_libdecor = xyes; then
-                AC_MSG_CHECKING(for libdecor support)
-                AS_IF([$PKG_CONFIG --exists libdecor-0],
-                      [video_libdecor=yes],
-                      [video_libdecor=no])
-                AC_MSG_RESULT($video_libdecor)
+                PKG_CHECK_MODULES([DECOR], [libdecor-0], video_libdecor=yes, video_libdecor=no)
                 if test x$video_libdecor = xyes; then
-                    EXTRA_CFLAGS="$EXTRA_CFLAGS `$PKG_CONFIG --cflags libdecor-0`"
+                    EXTRA_CFLAGS="$EXTRA_CFLAGS $DECOR_CFLAGS"
                     AC_DEFINE(HAVE_LIBDECOR_H, 1, [ ])
 
                     AC_ARG_ENABLE(libdecor-shared,
-[AS_HELP_STRING([--enable-libdecor-shared], [dynamically load libdecor [default=yes]])],
-                         , enable_libdecor_shared=yes)
+[AS_HELP_STRING([--enable-libdecor-shared], [dynamically load libdecor [default=yes]])],, enable_libdecor_shared=yes)
+
+                    decor_lib=[`find_lib "libdecor-0.so.*" "$DECOR_LIBS" | sed 's/.*\/\(.*\)/\1/; q'`]
 
                     if test x$enable_wayland_shared != xyes; then
                        enable_libdecor_shared=no
                     fi
-
-                    decor_lib=[`find_lib "libdecor-0.so.*" "" | sed 's/.*\/\(.*\)/\1/; q'`]
-
                     if test x$have_loadso != xyes && \
                        test x$enable_libdecor_shared = xyes; then
                         AC_MSG_WARN([You must have SDL_LoadObject() support for dynamic libdecor loading])
                     fi
-
                     if test x$have_loadso = xyes && \
                        test x$enable_libdecor_shared = xyes && test x$decor_lib != x; then
                         echo "-- dynamic libdecor -> $decor_lib"
                         AC_DEFINE_UNQUOTED(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR, "$decor_lib", [ ])
                     else
-                        EXTRA_LDFLAGS="$EXTRA_LDFLAGS `$PKG_CONFIG --libs libdecor-0`"
+                        EXTRA_LDFLAGS="$EXTRA_LDFLAGS $DECOR_LIBS"
                     fi
                 fi
             fi
@@ -3206,6 +3198,16 @@ CheckWINDOWS()
 
     # This fixes Windows stack alignment with newer GCC
     CheckStackBoundary
+
+    # headers needed elsewhere
+    AC_CHECK_HEADER(tpcshrd.h,have_tpcshrd_h=yes)
+    if test x$have_tpcshrd_h = xyes; then
+        AC_DEFINE(HAVE_TPCSHRD_H, 1, [ ])
+    fi
+    AC_CHECK_HEADER(roapi.h,have_roapi_h=yes)
+    if test x$have_roapi_h = xyes; then
+        AC_DEFINE(HAVE_ROAPI_H, 1, [ ])
+    fi
 }
 
 dnl Determine whether the compiler can produce OS/2 executables
@@ -4007,10 +4009,6 @@ case "$host" in
                 have_haptic=yes
             fi
         fi
-        AC_CHECK_HEADER(tpcshrd.h,have_tpcshrd_h=yes)
-        if test x$have_tpcshrd_h = xyes; then
-            AC_DEFINE(HAVE_TPCSHRD_H, 1, [ ])
-        fi
         # Set up files for the sensor library
         AC_CHECK_HEADER(sensorsapi.h,have_winsensors=yes,have_winsensors=no)
         if test x$have_winsensors = xyes; then

+ 29 - 13
Engine/lib/sdl/docs/README-directfb.md

@@ -15,29 +15,34 @@ What you need:
 * Kernel-Framebuffer support: required: vesafb, radeonfb .... 
 * Mesa 7.0.x	   - optional for OpenGL
 
-/etc/directfbrc
-
-This file should contain the following lines to make
+The `/etc/directfbrc` file should contain the following lines to make
 your joystick work and avoid crashes:
-------------------------
+
+```
 disable-module=joystick
 disable-module=cle266
 disable-module=cyber5k
 no-linux-input-grab
-------------------------
+```
 
 To disable to use x11 backend when DISPLAY variable is found use
 
+```
 export SDL_DIRECTFB_X11_CHECK=0
+```
 
 To disable the use of linux input devices, i.e. multimice/multikeyboard support,
 use
 
+```
 export SDL_DIRECTFB_LINUX_INPUT=0
+```
 
 To use hardware accelerated YUV-overlays for YUV-textures, use:
 
+```
 export SDL_DIRECTFB_YUV_DIRECT=1
+```
 
 This is disabled by default. It will only support one 
 YUV texture, namely the first. Every other YUV texture will be
@@ -45,7 +50,9 @@ rendered in software.
 
 In addition, you may use (directfb-1.2.x)
 
+```
 export SDL_DIRECTFB_YUV_UNDERLAY=1
+```
 
 to make the YUV texture an underlay. This will make the cursor to
 be shown.
@@ -54,14 +61,18 @@ Simple Window Manager
 =====================
 
 The driver has support for a very, very basic window manager you may
-want to use when running with "wm=default". Use
+want to use when running with `wm=default`. Use
 
+```
 export SDL_DIRECTFB_WM=1
+```
 
 to enable basic window borders. In order to have the window title rendered,
 you need to have the following font installed:
 
+```
 /usr/share/fonts/truetype/freefont/FreeSans.ttf
+```
 
 OpenGL Support
 ==============
@@ -71,21 +82,25 @@ works at least on all directfb supported platforms.
 
 As of this writing 20100802 you need to pull Mesa from git and do the following:
 
-------------------------
+```
 git clone git://anongit.freedesktop.org/git/mesa/mesa
 cd mesa 
 git checkout 2c9fdaf7292423c157fc79b5ce43f0f199dd753a
-------------------------
+```
+
+Edit `configs/linux-directfb` so that the Directories-section looks like this:
 
-Edit configs/linux-directfb so that the Directories-section looks like
-------------------------
+```
 # Directories
 SRC_DIRS     = mesa glu 
 GLU_DIRS     = sgi
 DRIVER_DIRS  = directfb
 PROGRAM_DIRS = 
-------------------------
+```
 
+Then do the following:
+
+```
 make linux-directfb
 make
 
@@ -95,13 +110,14 @@ sudo make install INSTALL_DIR=/usr/local/dfb_GL
 cd src/mesa/drivers/directfb
 make
 sudo make install INSTALL_DIR=/usr/local/dfb_GL
-------------------------
+```
 
 To run the SDL - testprograms:
 
+```
 export SDL_VIDEODRIVER=directfb
 export LD_LIBRARY_PATH=/usr/local/dfb_GL/lib
 export LD_PRELOAD=/usr/local/dfb_GL/libGL.so.7
 
 ./testgl
-
+```

+ 1 - 1
Engine/lib/sdl/docs/README-visualc.md

@@ -1,7 +1,7 @@
 Using SDL with Microsoft Visual C++
 ===================================
 
-### by [Lion Kimbro](mailto:[email protected]) with additions by [James Turk](mailto:[email protected])
+### by Lion Kimbro with additions by James Turk
 
 You can either use the precompiled libraries from the [SDL](https://www.libsdl.org/download.php) web site, or you can build SDL
 yourself.

+ 3 - 0
Engine/lib/sdl/docs/README-vita.md

@@ -22,6 +22,9 @@ Notes
 * gles1/gles2 support and renderers are disabled by default and can be enabled by configuring with `-DVIDEO_VITA_PVR=ON`
   These renderers support 720p and 1080i resolutions. These can be specified with: 
   `SDL_setenv("VITA_RESOLUTION", "720", 1);` and `SDL_setenv("VITA_RESOLUTION", "1080", 1);`
+* Desktop GL 1.X and 2.X support and renderers are also disabled by default and also can be enabled with `-DVIDEO_VITA_PVR=ON` as long as gl4es4vita is present in your SDK.
+  They support the same resolutions as the gles1/gles2 backends and require specifying `SDL_setenv("VITA_PVR_OGL", "1", 1);`
+  anytime before video subsystem initialization.
 * gles2 support via PIB is disabled by default and can be enabled by configuring with `-DVIDEO_VITA_PIB=ON`
 * By default SDL emits mouse events for touch events on every touchscreen.  
   Vita has two touchscreens, so it's recommended to use `SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");` and handle touch events instead.

+ 50 - 37
Engine/lib/sdl/docs/README-windows.md

@@ -1,45 +1,58 @@
-Windows
-================================================================================
-
-================================================================================
-OpenGL ES 2.x support
-================================================================================
-
-SDL has support for OpenGL ES 2.x under Windows via two alternative 
-implementations. 
-The most straightforward method consists in running your app in a system with 
-a graphic card paired with a relatively recent (as of November of 2013) driver 
-which supports the WGL_EXT_create_context_es2_profile extension. Vendors known 
+# Windows
+
+## LLVM and Intel C++ compiler support
+
+SDL will build with the Visual Studio project files with LLVM-based compilers, such as the Intel oneAPI C++
+compiler, but you'll have to manually add the "-msse3" command line option
+to at least the SDL_audiocvt.c source file, and possibly others. This may
+not be necessary if you build SDL with CMake instead of the included Visual
+Studio solution.
+
+Details are here: https://github.com/libsdl-org/SDL/issues/5186
+
+
+## OpenGL ES 2.x support
+
+SDL has support for OpenGL ES 2.x under Windows via two alternative
+implementations.
+
+The most straightforward method consists in running your app in a system with
+a graphic card paired with a relatively recent (as of November of 2013) driver
+which supports the WGL_EXT_create_context_es2_profile extension. Vendors known
 to ship said extension on Windows currently include nVidia and Intel.
 
-The other method involves using the ANGLE library (https://code.google.com/p/angleproject/)
-If an OpenGL ES 2.x context is requested and no WGL_EXT_create_context_es2_profile
-extension is found, SDL will try to load the libEGL.dll library provided by
-ANGLE.
+The other method involves using the
+[ANGLE library](https://code.google.com/p/angleproject/). If an OpenGL ES 2.x
+context is requested and no WGL_EXT_create_context_es2_profile extension is
+found, SDL will try to load the libEGL.dll library provided by ANGLE.
+
 To obtain the ANGLE binaries, you can either compile from source from
-https://chromium.googlesource.com/angle/angle or copy the relevant binaries from
-a recent Chrome/Chromium install for Windows. The files you need are:
-    
-    * libEGL.dll
-    * libGLESv2.dll
-    * d3dcompiler_46.dll (supports Windows Vista or later, better shader compiler)
-    or...
-    * d3dcompiler_43.dll (supports Windows XP or later)
+https://chromium.googlesource.com/angle/angle or copy the relevant binaries
+from a recent Chrome/Chromium install for Windows. The files you need are:
+
+- libEGL.dll
+- libGLESv2.dll
+- d3dcompiler_46.dll (supports Windows Vista or later, better shader
+  compiler) *or* d3dcompiler_43.dll (supports Windows XP or later)
     
 If you compile ANGLE from source, you can configure it so it does not need the
-d3dcompiler_* DLL at all (for details on this, see their documentation). 
+d3dcompiler_* DLL at all (for details on this, see their documentation).
 However, by default SDL will try to preload the d3dcompiler_46.dll to
-comply with ANGLE's requirements. If you wish SDL to preload d3dcompiler_43.dll (to
-support Windows XP) or to skip this step at all, you can use the 
-SDL_HINT_VIDEO_WIN_D3DCOMPILER hint (see SDL_hints.h for more details).
+comply with ANGLE's requirements. If you wish SDL to preload
+d3dcompiler_43.dll (to support Windows XP) or to skip this step at all, you
+can use the SDL_HINT_VIDEO_WIN_D3DCOMPILER hint (see SDL_hints.h for more
+details).
 
 Known Bugs:
-    
-    * SDL_GL_SetSwapInterval is currently a no op when using ANGLE. It appears
-      that there's a bug in the library which prevents the window contents from
-      refreshing if this is set to anything other than the default value.
-     
-Vulkan Surface Support
-==============
-
-Support for creating Vulkan surfaces is configured on by default. To disable it change the value of `SDL_VIDEO_VULKAN` to 0 in `SDL_config_windows.h`. You must install the [Vulkan SDK](https://www.lunarg.com/vulkan-sdk/) in order to use Vulkan graphics in your application.
+
+- SDL_GL_SetSwapInterval is currently a no op when using ANGLE. It appears
+  that there's a bug in the library which prevents the window contents from
+  refreshing if this is set to anything other than the default value.
+  
+## Vulkan Surface Support
+
+Support for creating Vulkan surfaces is configured on by default. To disable
+it change the value of `SDL_VIDEO_VULKAN` to 0 in `SDL_config_windows.h`. You
+must install the [Vulkan SDK](https://www.lunarg.com/vulkan-sdk/) in order to
+use Vulkan graphics in your application.
+

+ 4 - 6
Engine/lib/sdl/include/SDL_blendmode.h

@@ -67,9 +67,8 @@ typedef enum
     SDL_BLENDOPERATION_ADD              = 0x1,  /**< dst + src: supported by all renderers */
     SDL_BLENDOPERATION_SUBTRACT         = 0x2,  /**< dst - src : supported by D3D9, D3D11, OpenGL, OpenGLES */
     SDL_BLENDOPERATION_REV_SUBTRACT     = 0x3,  /**< src - dst : supported by D3D9, D3D11, OpenGL, OpenGLES */
-    SDL_BLENDOPERATION_MINIMUM          = 0x4,  /**< min(dst, src) : supported by D3D11 */
-    SDL_BLENDOPERATION_MAXIMUM          = 0x5   /**< max(dst, src) : supported by D3D11 */
-
+    SDL_BLENDOPERATION_MINIMUM          = 0x4,  /**< min(dst, src) : supported by D3D9, D3D11 */
+    SDL_BLENDOPERATION_MAXIMUM          = 0x5   /**< max(dst, src) : supported by D3D9, D3D11 */
 } SDL_BlendOperation;
 
 /**
@@ -87,7 +86,6 @@ typedef enum
     SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR = 0x8,  /**< 1-dstR, 1-dstG, 1-dstB, 1-dstA */
     SDL_BLENDFACTOR_DST_ALPHA           = 0x9,  /**< dstA, dstA, dstA, dstA */
     SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA = 0xA   /**< 1-dstA, 1-dstA, 1-dstA, 1-dstA */
-
 } SDL_BlendFactor;
 
 /**
@@ -135,10 +133,10 @@ typedef enum
  * SDL 2.0.6. All renderers support the four blend modes listed in the
  * SDL_BlendMode enumeration.
  *
- * - **direct3d**: Supports `SDL_BLENDOPERATION_ADD` with all factors.
- * - **direct3d11**: Supports all operations with all factors. However, some
+ * - **direct3d**: Supports all operations with all factors. However, some
  *   factors produce unexpected results with `SDL_BLENDOPERATION_MINIMUM` and
  *   `SDL_BLENDOPERATION_MAXIMUM`.
+ * - **direct3d11**: Same as Direct3D 9.
  * - **opengl**: Supports the `SDL_BLENDOPERATION_ADD` operation with all
  *   factors. OpenGL versions 1.1, 1.2, and 1.3 do not work correctly with SDL
  *   2.0.6.

+ 2 - 0
Engine/lib/sdl/include/SDL_config.h.cmake

@@ -253,6 +253,7 @@
 #cmakedefine HAVE_AUDIOCLIENT_H @HAVE_AUDIOCLIENT_H@
 #cmakedefine HAVE_TPCSHRD_H @HAVE_TPCSHRD_H@
 #cmakedefine HAVE_SENSORSAPI_H @HAVE_SENSORSAPI_H@
+#cmakedefine HAVE_ROAPI_H @HAVE_ROAPI_H@
 
 #cmakedefine HAVE_XINPUT_GAMEPAD_EX @HAVE_XINPUT_GAMEPAD_EX@
 #cmakedefine HAVE_XINPUT_STATE_EX @HAVE_XINPUT_STATE_EX@
@@ -520,6 +521,7 @@
 
 #cmakedefine SDL_VIDEO_VITA_PIB @SDL_VIDEO_VITA_PIB@
 #cmakedefine SDL_VIDEO_VITA_PVR @SDL_VIDEO_VITA_PVR@
+#cmakedefine SDL_VIDEO_VITA_PVR_OGL @SDL_VIDEO_VITA_PVR_OGL@
 
 #if !defined(__WIN32__) && !defined(__WINRT__)
 #  if !defined(_STDINT_H_) && !defined(_STDINT_H) && !defined(HAVE_STDINT_H) && !defined(_HAVE_STDINT_H)

+ 1 - 0
Engine/lib/sdl/include/SDL_config.h.in

@@ -242,6 +242,7 @@
 #undef HAVE_AUDIOCLIENT_H
 #undef HAVE_TPCSHRD_H
 #undef HAVE_SENSORSAPI_H
+#undef HAVE_ROAPI_H
 
 /* SDL internal assertion support */
 #undef SDL_DEFAULT_ASSERT_LEVEL

+ 1 - 0
Engine/lib/sdl/include/SDL_config_emscripten.h

@@ -185,6 +185,7 @@
 /* Enable various threading systems */
 #ifdef __EMSCRIPTEN_PTHREADS__
 #define SDL_THREAD_PTHREAD 1
+#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1
 #endif
 
 /* Enable various timer systems */

+ 1 - 0
Engine/lib/sdl/include/SDL_config_windows.h

@@ -104,6 +104,7 @@ typedef unsigned int uintptr_t;
 #endif
 #if defined(_WIN32_MAXVER) && _WIN32_MAXVER >= 0x0602  /* Windows 8 SDK */
 #define HAVE_D3D11_H 1
+#define HAVE_ROAPI_H 1
 #endif
 #define HAVE_MMDEVICEAPI_H 1
 #define HAVE_AUDIOCLIENT_H 1

+ 2 - 0
Engine/lib/sdl/include/SDL_config_winrt.h

@@ -195,6 +195,8 @@ typedef unsigned int uintptr_t;
 #define HAVE_TRUNCF 1
 #define HAVE__FSEEKI64 1
 
+#define HAVE_ROAPI_H  1
+
 /* Enable various audio drivers */
 #define SDL_AUDIO_DRIVER_WASAPI 1
 #define SDL_AUDIO_DRIVER_DISK   1

+ 74 - 2
Engine/lib/sdl/include/SDL_hints.h

@@ -1354,6 +1354,18 @@ extern "C" {
  */
 #define SDL_HINT_TOUCH_MOUSE_EVENTS    "SDL_TOUCH_MOUSE_EVENTS"
 
+/**
+ *  \brief  A variable controlling which touchpad should generate synthetic mouse events
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - Only front touchpad should generate mouse events. Default
+ *    "1"       - Only back touchpad should generate mouse events.
+ *    "2"       - Both touchpads should generate mouse events.
+ *
+ *  By default SDL will generate mouse events for all touch devices
+ */
+#define SDL_HINT_VITA_TOUCH_MOUSE_DEVICE    "SDL_HINT_VITA_TOUCH_MOUSE_DEVICE"
+
 /**
  *  \brief  A variable controlling whether the Android / tvOS remotes
  *  should be listed as joystick devices, instead of sending keyboard events.
@@ -1463,6 +1475,20 @@ extern "C" {
  */
 #define SDL_HINT_VIDEO_WAYLAND_ALLOW_LIBDECOR "SDL_VIDEO_WAYLAND_ALLOW_LIBDECOR"
 
+/**
+ *  \brief  A variable controlling whether the libdecor Wayland backend is preferred over native decrations.
+ *
+ *  When this hint is set, libdecor will be used to provide window decorations, even if xdg-decoration is
+ *  available. (Note that, by default, libdecor will use xdg-decoration itself if available).
+ *
+ *  This variable can be set to the following values:
+ *    "0"       - libdecor is enabled only if server-side decorations are unavailable.
+ *    "1"       - libdecor is always enabled if available.
+ *
+ *  libdecor is used over xdg-shell when xdg-decoration protocol is unavailable.
+ */
+#define SDL_HINT_VIDEO_WAYLAND_PREFER_LIBDECOR "SDL_VIDEO_WAYLAND_PREFER_LIBDECOR"
+
 /**
 *  \brief  A variable that is the address of another SDL_Window* (as a hex string formatted with "%p").
 *  
@@ -1938,8 +1964,7 @@ extern "C" {
  *  If not set or set to "", this hint is ignored. This hint must be set
  *  before the SDL_CreateWindow() call that it is intended to affect.
  *
- *  This hint is available since SDL 2.0.22. Before then, virtual devices are
- *  always ignored.
+ *  This hint is available since SDL 2.0.22.
  */
 #define SDL_HINT_X11_WINDOW_TYPE "SDL_X11_WINDOW_TYPE"
 
@@ -1968,6 +1993,53 @@ extern "C" {
 #define SDL_HINT_QUIT_ON_LAST_WINDOW_CLOSE "SDL_QUIT_ON_LAST_WINDOW_CLOSE"
 
 
+/**
+ *  \brief  A variable that decides what video backend to use.
+ *
+ *  By default, SDL will try all available video backends in a reasonable
+ *  order until it finds one that can work, but this hint allows the app
+ *  or user to force a specific target, such as "x11" if, say, you are
+ *  on Wayland but want to try talking to the X server instead.
+ *
+ *  This functionality has existed since SDL 2.0.0 (indeed, before that)
+ *  but before 2.0.22 this was an environment variable only. In 2.0.22,
+ *  it was upgraded to a full SDL hint, so you can set the environment
+ *  variable as usual or programatically set the hint with SDL_SetHint,
+ *  which won't propagate to child processes.
+ *
+ *  The default value is unset, in which case SDL will try to figure out
+ *  the best video backend on your behalf. This hint needs to be set
+ *  before SDL_Init() is called to be useful.
+ *
+ *  This hint is available since SDL 2.0.22. Before then, you could set
+ *  the environment variable to get the same effect.
+ */
+#define SDL_HINT_VIDEODRIVER "SDL_VIDEODRIVER"
+
+/**
+ *  \brief  A variable that decides what audio backend to use.
+ *
+ *  By default, SDL will try all available audio backends in a reasonable
+ *  order until it finds one that can work, but this hint allows the app
+ *  or user to force a specific target, such as "alsa" if, say, you are
+ *  on PulseAudio but want to try talking to the lower level instead.
+ *
+ *  This functionality has existed since SDL 2.0.0 (indeed, before that)
+ *  but before 2.0.22 this was an environment variable only. In 2.0.22,
+ *  it was upgraded to a full SDL hint, so you can set the environment
+ *  variable as usual or programatically set the hint with SDL_SetHint,
+ *  which won't propagate to child processes.
+ *
+ *  The default value is unset, in which case SDL will try to figure out
+ *  the best audio backend on your behalf. This hint needs to be set
+ *  before SDL_Init() is called to be useful.
+ *
+ *  This hint is available since SDL 2.0.22. Before then, you could set
+ *  the environment variable to get the same effect.
+ */
+#define SDL_HINT_AUDIODRIVER "SDL_AUDIODRIVER"
+
+
 /**
  *  \brief  An enumeration of hint priorities
  */

+ 1 - 0
Engine/lib/sdl/include/SDL_metal.h

@@ -92,6 +92,7 @@ extern DECLSPEC void *SDLCALL SDL_Metal_GetLayer(SDL_MetalView view);
  *
  * \param window SDL_Window from which the drawable size should be queried
  * \param w Pointer to variable for storing the width in pixels, may be NULL
+ * \param h Pointer to variable for storing the height in pixels, may be NULL
  *
  * \since This function is available since SDL 2.0.14.
  *

+ 30 - 8
Engine/lib/sdl/include/SDL_rect.h

@@ -54,11 +54,6 @@ typedef struct SDL_Point
 /**
  * The structure that defines a point (floating point)
  *
- * \sa SDL_FRectEmpty
- * \sa SDL_FRectEquals
- * \sa SDL_HasIntersectionF
- * \sa SDL_IntersectFRect
- * \sa SDL_UnionFRect
  * \sa SDL_EncloseFPoints
  * \sa SDL_PointInFRect
  */
@@ -76,6 +71,7 @@ typedef struct SDL_FPoint
  * \sa SDL_RectEquals
  * \sa SDL_HasIntersection
  * \sa SDL_IntersectRect
+ * \sa SDL_IntersectRectAndLine
  * \sa SDL_UnionRect
  * \sa SDL_EnclosePoints
  */
@@ -88,6 +84,16 @@ typedef struct SDL_Rect
 
 /**
  * A rectangle, with the origin at the upper left (floating point).
+ *
+ * \sa SDL_FRectEmpty
+ * \sa SDL_FRectEquals
+ * \sa SDL_FRectEqualsEpsilon
+ * \sa SDL_HasIntersectionF
+ * \sa SDL_IntersectFRect
+ * \sa SDL_IntersectFRectAndLine
+ * \sa SDL_UnionFRect
+ * \sa SDL_EncloseFPoints
+ * \sa SDL_PointInFRect
  */
 typedef struct SDL_FRect
 {
@@ -239,12 +245,28 @@ SDL_FORCE_INLINE SDL_bool SDL_FRectEmpty(const SDL_FRect *r)
 }
 
 /**
- * Returns true if the two rectangles are equal.
+ * Returns true if the two rectangles are equal, within some given epsilon.
+ *
+ * \since This function is available since SDL 2.0.22.
+ */
+SDL_FORCE_INLINE SDL_bool SDL_FRectEqualsEpsilon(const SDL_FRect *a, const SDL_FRect *b, const float epsilon)
+{
+    return (a && b && ((a == b) ||
+            ((SDL_fabs(a->x - b->x) <= epsilon) &&
+            (SDL_fabs(a->y - b->y) <= epsilon) &&
+            (SDL_fabs(a->w - b->w) <= epsilon) &&
+            (SDL_fabs(a->h - b->h) <= epsilon))))
+            ? SDL_TRUE : SDL_FALSE;
+}
+
+/**
+ * Returns true if the two rectangles are equal, using a default epsilon.
+ *
+ * \since This function is available since SDL 2.0.22.
  */
 SDL_FORCE_INLINE SDL_bool SDL_FRectEquals(const SDL_FRect *a, const SDL_FRect *b)
 {
-    return (a && b && (a->x == b->x) && (a->y == b->y) &&
-            (a->w == b->w) && (a->h == b->h)) ? SDL_TRUE : SDL_FALSE;
+    return SDL_FRectEqualsEpsilon(a, b, SDL_FLT_EPSILON);
 }
 
 /**

+ 13 - 0
Engine/lib/sdl/include/SDL_render.h

@@ -261,6 +261,17 @@ extern DECLSPEC SDL_Renderer * SDLCALL SDL_CreateSoftwareRenderer(SDL_Surface *
  */
 extern DECLSPEC SDL_Renderer * SDLCALL SDL_GetRenderer(SDL_Window * window);
 
+/**
+ * Get the window associated with a renderer.
+ *
+ * \param renderer the renderer to query
+ * \returns the window on success or NULL on failure; call SDL_GetError() for
+ *          more information.
+ *
+ * \since This function is available since SDL 2.0.22.
+ */
+extern DECLSPEC SDL_Window * SDLCALL SDL_RenderGetWindow(SDL_Renderer *renderer);
+
 /**
  * Get information about a rendering context.
  *
@@ -1607,6 +1618,7 @@ extern DECLSPEC int SDLCALL SDL_RenderCopyExF(SDL_Renderer * renderer,
  * vertex array Color and alpha modulation is done per vertex
  * (SDL_SetTextureColorMod and SDL_SetTextureAlphaMod are ignored).
  *
+ * \param renderer The rendering context.
  * \param texture (optional) The SDL texture to use.
  * \param vertices Vertices.
  * \param num_vertices Number of vertices.
@@ -1631,6 +1643,7 @@ extern DECLSPEC int SDLCALL SDL_RenderGeometry(SDL_Renderer *renderer,
  * vertex arrays Color and alpha modulation is done per vertex
  * (SDL_SetTextureColorMod and SDL_SetTextureAlphaMod are ignored).
  *
+ * \param renderer The rendering context.
  * \param texture (optional) The SDL texture to use.
  * \param xy Vertex positions
  * \param xy_stride Byte size to move from one element to the next element

+ 15 - 2
Engine/lib/sdl/include/SDL_stdinc.h

@@ -234,6 +234,19 @@ typedef uint64_t Uint64;
 
 /* @} *//* Basic data types */
 
+/**
+ *  \name Floating-point constants
+ */
+/* @{ */
+
+#ifdef FLT_EPSILON
+#define SDL_FLT_EPSILON FLT_EPSILON
+#else
+#define SDL_FLT_EPSILON 1.1920928955078125e-07F /* 0x0.000002p0 */
+#endif
+
+/* @} *//* Floating-point constants */
+
 /* Make sure we have macros for printing width-based integers.
  * <stdint.h> should define these but this is not true all platforms.
  * (for example win32) */
@@ -355,9 +368,9 @@ typedef uint64_t Uint64;
 #endif /* SDL_DISABLE_ANALYZE_MACROS */
 
 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
-#define SDL_COMPILE_TIME_ASSERT(name, x) _Static_assert(x, #x);
+#define SDL_COMPILE_TIME_ASSERT(name, x) _Static_assert(x, #x)
 #elif defined(__cplusplus) && (__cplusplus >= 201103L)
-#define SDL_COMPILE_TIME_ASSERT(name, x)  static_assert(x, #x);
+#define SDL_COMPILE_TIME_ASSERT(name, x)  static_assert(x, #x)
 #else /* universal, but may trigger -Wunused-local-typedefs */
 #define SDL_COMPILE_TIME_ASSERT(name, x)               \
        typedef int SDL_compile_time_assert_ ## name[(x) * 2 - 1]

+ 2 - 0
Engine/lib/sdl/include/SDL_syswm.h

@@ -298,6 +298,8 @@ struct SDL_SysWMinfo
             struct wl_egl_window *egl_window;       /**< Wayland EGL window (native window) */
             struct xdg_surface *xdg_surface;        /**< Wayland xdg surface (window manager handle) */
             struct xdg_toplevel *xdg_toplevel;      /**< Wayland xdg toplevel role */
+            struct xdg_popup *xdg_popup;            /**< Wayland xdg popup role */
+            struct xdg_positioner *xdg_positioner;  /**< Wayland xdg positioner, for popup */
         } wl;
 #endif
 #if defined(SDL_VIDEO_DRIVER_MIR)  /* no longer available, left for API/ABI compatibility. Remove in 2.1! */

+ 1 - 1
Engine/lib/sdl/include/SDL_version.h

@@ -59,7 +59,7 @@ typedef struct SDL_version
 */
 #define SDL_MAJOR_VERSION   2
 #define SDL_MINOR_VERSION   0
-#define SDL_PATCHLEVEL      21
+#define SDL_PATCHLEVEL      22
 
 /**
  * Macro to determine SDL version program was compiled against.

+ 1 - 0
Engine/lib/sdl/include/SDL_video.h

@@ -1337,6 +1337,7 @@ extern DECLSPEC void SDLCALL SDL_SetWindowKeyboardGrab(SDL_Window * window,
  * Mouse grab confines the mouse cursor to the window.
  *
  * \param window The window for which the mouse grab mode should be set.
+ * \param grabbed This is SDL_TRUE to grab mouse, and SDL_FALSE to release.
  *
  * \since This function is available since SDL 2.0.16.
  *

+ 1 - 1
Engine/lib/sdl/include/begin_code.h

@@ -107,7 +107,7 @@
 #ifdef __BORLANDC__
 #pragma nopackwarning
 #endif
-#ifdef _M_X64
+#ifdef _WIN64
 /* Use 8-byte alignment on 64-bit architectures, so pointers are aligned */
 #pragma pack(push,8)
 #else

+ 2 - 0
Engine/lib/sdl/src/SDL.c

@@ -316,6 +316,8 @@ SDL_InitSubSystem(Uint32 flags)
 #endif
     }
 
+    (void) flags_initialized;  /* make static analysis happy, since this only gets used in error cases. */
+
     return (0);
 
 quit_and_error:

+ 5 - 0
Engine/lib/sdl/src/SDL_hints.c

@@ -178,6 +178,11 @@ SDL_AddHintCallback(const char *name, SDL_HintCallback callback, void *userdata)
             return;
         }
         hint->name = SDL_strdup(name);
+        if (!hint->name) {
+            SDL_free(hint);
+            SDL_OutOfMemory();
+            return;
+        }
         hint->value = NULL;
         hint->priority = SDL_HINT_DEFAULT;
         hint->callbacks = NULL;

+ 93 - 0
Engine/lib/sdl/src/SDL_list.c

@@ -0,0 +1,93 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2022 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, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#include "./SDL_internal.h"
+
+#include "SDL.h"
+#include "./SDL_list.h"
+
+/* Push */
+int
+SDL_ListAdd(SDL_ListNode **head, void *ent)
+{
+    SDL_ListNode *node = SDL_malloc(sizeof (*node));
+
+    if (node == NULL) {
+        return SDL_OutOfMemory();
+    }
+
+    node->entry = ent;
+    node->next = *head;
+    *head = node;
+    return 0;
+}
+
+/* Pop from end as a FIFO (if add with SDL_ListAdd) */
+void
+SDL_ListPop(SDL_ListNode **head, void **ent)
+{
+    SDL_ListNode **ptr = head;
+
+    /* Invalid or empty */
+    if (head == NULL || *head == NULL) {
+        return;
+    }
+
+    while ((*ptr)->next) {
+        ptr = &(*ptr)->next;
+    }
+
+    if (ent) {
+       *ent = (*ptr)->entry;
+    }
+
+    SDL_free(*ptr);
+    *ptr = NULL;
+}
+
+void
+SDL_ListRemove(SDL_ListNode **head, void *ent)
+{
+    SDL_ListNode **ptr = head;
+
+    while (*ptr) {
+        if ((*ptr)->entry == ent) {
+            SDL_ListNode *tmp = *ptr;
+            *ptr = (*ptr)->next;
+            SDL_free(tmp);
+            return;
+        }
+        ptr = &(*ptr)->next;
+    }
+}
+
+void
+SDL_ListClear(SDL_ListNode **head)
+{
+    SDL_ListNode *l = *head;
+    *head = NULL;
+    while (l) {
+        SDL_ListNode *tmp = l;
+        l = l->next;
+        SDL_free(tmp);
+    }
+}
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 39 - 0
Engine/lib/sdl/src/SDL_list.h

@@ -0,0 +1,39 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2022 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, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_list_h_
+#define SDL_list_h_
+
+typedef struct SDL_ListNode
+{
+    void *entry;
+    struct SDL_ListNode *next;
+} SDL_ListNode;
+
+
+int SDL_ListAdd(SDL_ListNode **head, void *ent);
+void SDL_ListPop(SDL_ListNode **head, void **ent);
+void SDL_ListRemove(SDL_ListNode **head, void *ent);
+void SDL_ListClear(SDL_ListNode **head);
+
+#endif /* SDL_list_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 1 - 1
Engine/lib/sdl/src/audio/SDL_audio.c

@@ -936,7 +936,7 @@ SDL_AudioInit(const char *driver_name)
 
     /* Select the proper audio driver */
     if (driver_name == NULL) {
-        driver_name = SDL_getenv("SDL_AUDIODRIVER");
+        driver_name = SDL_GetHint(SDL_HINT_AUDIODRIVER);
     }
 
     if (driver_name != NULL && *driver_name != 0) {

+ 1 - 1
Engine/lib/sdl/src/audio/SDL_audiocvt.c

@@ -80,7 +80,7 @@ SDL_ConvertStereoToMono_SSE3(SDL_AudioCVT * cvt, SDL_AudioFormat format)
        Just use unaligned load/stores, if the memory at runtime is
        aligned it'll be just as fast on modern processors */
     while (i >= 4) {   /* 4 * float32 */
-        _mm_storeu_ps(dst, _mm_mul_ps(_mm_hadd_ps(_mm_load_ps(src), _mm_loadu_ps(src+4)), divby2));
+        _mm_storeu_ps(dst, _mm_mul_ps(_mm_hadd_ps(_mm_loadu_ps(src), _mm_loadu_ps(src+4)), divby2));
         i -= 4; src += 8; dst += 4;
     }
 

+ 1 - 1
Engine/lib/sdl/src/audio/SDL_wave.c

@@ -685,7 +685,7 @@ MS_ADPCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len)
 
     state.output.pos = 0;
     state.output.size = outputsize / sizeof(Sint16);
-    state.output.data = (Sint16 *)SDL_malloc(outputsize);
+    state.output.data = (Sint16 *)SDL_calloc(1, outputsize);
     if (state.output.data == NULL) {
         return SDL_OutOfMemory();
     }

+ 8 - 8
Engine/lib/sdl/src/audio/emscripten/SDL_emscriptenaudio.c

@@ -32,7 +32,7 @@ static void
 FeedAudioDevice(_THIS, const void *buf, const int buflen)
 {
     const int framelen = (SDL_AUDIO_BITSIZE(this->spec.format) / 8) * this->spec.channels;
-    EM_ASM_ARGS({
+    MAIN_THREAD_EM_ASM({
         var SDL2 = Module['SDL2'];
         var numChannels = SDL2.audio.currentOutputBuffer['numberOfChannels'];
         for (var c = 0; c < numChannels; ++c) {
@@ -101,7 +101,7 @@ HandleCaptureProcess(_THIS)
         return;
     }
 
-    EM_ASM_ARGS({
+    MAIN_THREAD_EM_ASM({
         var SDL2 = Module['SDL2'];
         var numChannels = SDL2.capture.currentCaptureBuffer.numberOfChannels;
         for (var c = 0; c < numChannels; ++c) {
@@ -147,7 +147,7 @@ HandleCaptureProcess(_THIS)
 static void
 EMSCRIPTENAUDIO_CloseDevice(_THIS)
 {
-    EM_ASM_({
+    MAIN_THREAD_EM_ASM({
         var SDL2 = Module['SDL2'];
         if ($0) {
             if (SDL2.capture.silenceTimer !== undefined) {
@@ -201,7 +201,7 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
     /* based on parts of library_sdl.js */
 
     /* create context */
-    result = EM_ASM_INT({
+    result = MAIN_THREAD_EM_ASM_INT({
         if(typeof(Module['SDL2']) === 'undefined') {
             Module['SDL2'] = {};
         }
@@ -280,7 +280,7 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
            feels like it's a pretty inefficient tapdance in similar ways,
            to be honest. */
 
-        EM_ASM_({
+        MAIN_THREAD_EM_ASM({
             var SDL2 = Module['SDL2'];
             var have_microphone = function(stream) {
                 //console.log('SDL audio capture: we have a microphone! Replacing silence callback.');
@@ -323,7 +323,7 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
         }, this->spec.channels, this->spec.samples, HandleCaptureProcess, this);
     } else {
         /* setup a ScriptProcessorNode */
-        EM_ASM_ARGS({
+        MAIN_THREAD_EM_ASM({
             var SDL2 = Module['SDL2'];
             SDL2.audio.scriptProcessorNode = SDL2.audioContext['createScriptProcessor']($1, 0, $0);
             SDL2.audio.scriptProcessorNode['onaudioprocess'] = function (e) {
@@ -359,7 +359,7 @@ EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl * impl)
     impl->ProvidesOwnCallbackThread = SDL_TRUE;
 
     /* check availability */
-    available = EM_ASM_INT_V({
+    available = MAIN_THREAD_EM_ASM_INT({
         if (typeof(AudioContext) !== 'undefined') {
             return true;
         } else if (typeof(webkitAudioContext) !== 'undefined') {
@@ -372,7 +372,7 @@ EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl * impl)
         SDL_SetError("No audio context available");
     }
 
-    capture_available = available && EM_ASM_INT_V({
+    capture_available = available && MAIN_THREAD_EM_ASM_INT({
         if ((typeof(navigator.mediaDevices) !== 'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !== 'undefined')) {
             return true;
         } else if (typeof(navigator.webkitGetUserMedia) !== 'undefined') {

+ 63 - 22
Engine/lib/sdl/src/audio/vita/SDL_vitaaudio.c

@@ -37,18 +37,35 @@
 
 #include <psp2/kernel/threadmgr.h>
 #include <psp2/audioout.h>
+#include <psp2/audioin.h>
 
 #define SCE_AUDIO_SAMPLE_ALIGN(s)   (((s) + 63) & ~63)
 #define SCE_AUDIO_MAX_VOLUME    0x8000
 
-/* The tag name used by VITA audio */
-#define VITAAUD_DRIVER_NAME     "vita"
+static int
+VITAAUD_OpenCaptureDevice(_THIS)
+{
+    this->spec.freq = 16000;
+    this->spec.samples = 512;
+    this->spec.channels = 1;
+
+    SDL_CalculateAudioSpec(&this->spec);
+
+    this->hidden->port = sceAudioInOpenPort(SCE_AUDIO_IN_PORT_TYPE_VOICE , 512, 16000, SCE_AUDIO_IN_PARAM_FORMAT_S16_MONO);
+
+    if (this->hidden->port < 0) {
+        return SDL_SetError("Couldn't open audio in port: %x", this->hidden->port);
+    }
+
+    return 0;
+}
 
 static int
 VITAAUD_OpenDevice(_THIS, const char *devname)
 {
     int format, mixlen, i, port = SCE_AUDIO_OUT_PORT_TYPE_MAIN;
     int vols[2] = {SCE_AUDIO_MAX_VOLUME, SCE_AUDIO_MAX_VOLUME};
+    SDL_AudioFormat test_format;
 
     this->hidden = (struct SDL_PrivateAudioData *)
         SDL_malloc(sizeof(*this->hidden));
@@ -56,13 +73,20 @@ VITAAUD_OpenDevice(_THIS, const char *devname)
         return SDL_OutOfMemory();
     }
     SDL_memset(this->hidden, 0, sizeof(*this->hidden));
-    switch (this->spec.format & 0xff) {
-        case 8:
-        case 16:
-            this->spec.format = AUDIO_S16LSB;
+
+    for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
+        if (test_format == AUDIO_S16LSB) {
+            this->spec.format = test_format;
             break;
-        default:
-            return SDL_SetError("Unsupported audio format");
+        }
+    }
+
+    if(!test_format) {
+        return SDL_SetError("Unsupported audio format");
+    }
+
+    if (this->iscapture) {
+        return VITAAUD_OpenCaptureDevice(this);
     }
 
     /* The sample count must be a multiple of 64. */
@@ -91,14 +115,14 @@ VITAAUD_OpenDevice(_THIS, const char *devname)
         port = SCE_AUDIO_OUT_PORT_TYPE_BGM;
     }
 
-    this->hidden->channel = sceAudioOutOpenPort(port, this->spec.samples, this->spec.freq, format);
-    if (this->hidden->channel < 0) {
+    this->hidden->port = sceAudioOutOpenPort(port, this->spec.samples, this->spec.freq, format);
+    if (this->hidden->port < 0) {
         free(this->hidden->rawbuf);
         this->hidden->rawbuf = NULL;
-        return SDL_SetError("Couldn't reserve hardware channel");
+        return SDL_SetError("Couldn't open audio out port: %x", this->hidden->port);
     }
 
-    sceAudioOutSetVolume(this->hidden->channel, SCE_AUDIO_VOLUME_FLAG_L_CH|SCE_AUDIO_VOLUME_FLAG_R_CH, vols);
+    sceAudioOutSetVolume(this->hidden->port, SCE_AUDIO_VOLUME_FLAG_L_CH|SCE_AUDIO_VOLUME_FLAG_R_CH, vols);
 
     SDL_memset(this->hidden->rawbuf, 0, mixlen);
     for (i = 0; i < NUM_BUFFERS; i++) {
@@ -113,7 +137,7 @@ static void VITAAUD_PlayDevice(_THIS)
 {
     Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer];
 
-    sceAudioOutOutput(this->hidden->channel, mixbuf);
+    sceAudioOutOutput(this->hidden->port, mixbuf);
 
     this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS;
 }
@@ -123,6 +147,7 @@ static void VITAAUD_WaitDevice(_THIS)
 {
     /* Because we block when sending audio, there's no need for this function to do anything. */
 }
+
 static Uint8 *VITAAUD_GetDeviceBuf(_THIS)
 {
     return this->hidden->mixbufs[this->hidden->next_buffer];
@@ -130,17 +155,32 @@ static Uint8 *VITAAUD_GetDeviceBuf(_THIS)
 
 static void VITAAUD_CloseDevice(_THIS)
 {
-    if (this->hidden->channel >= 0) {
-        sceAudioOutReleasePort(this->hidden->channel);
-        this->hidden->channel = -1;
+    if (this->hidden->port >= 0) {
+        if (this->iscapture) {
+            sceAudioInReleasePort(this->hidden->port);
+        } else {
+            sceAudioOutReleasePort(this->hidden->port);
+        }
+        this->hidden->port = -1;
     }
 
-    if (this->hidden->rawbuf != NULL) {
+    if (!this->iscapture && this->hidden->rawbuf != NULL) {
         free(this->hidden->rawbuf);         /* this uses memalign(), not SDL_malloc(). */
         this->hidden->rawbuf = NULL;
     }
 }
 
+static int VITAAUD_CaptureFromDevice(_THIS, void *buffer, int buflen)
+{
+    int ret;
+    SDL_assert(buflen == this->spec.size);
+    ret = sceAudioInInput(this->hidden->port, buffer);
+    if (ret < 0) {
+        return SDL_SetError("Failed to capture from device: %x", ret);
+    }
+    return this->spec.size;
+}
+
 static void VITAAUD_ThreadInit(_THIS)
 {
     /* Increase the priority of this audio thread by 1 to put it
@@ -165,12 +205,13 @@ VITAAUD_Init(SDL_AudioDriverImpl * impl)
     impl->CloseDevice = VITAAUD_CloseDevice;
     impl->ThreadInit = VITAAUD_ThreadInit;
 
-    /* VITA audio device */
-    impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
-    /*
+    impl->CaptureFromDevice = VITAAUD_CaptureFromDevice;
+
+    /* and the capabilities */
     impl->HasCaptureSupport = SDL_TRUE;
-    impl->OnlyHasDefaultInputDevice = SDL_TRUE;
-    */
+    impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
+    impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
+
     return SDL_TRUE;   /* this audio target is available. */
 }
 

+ 2 - 2
Engine/lib/sdl/src/audio/vita/SDL_vitaaudio.h

@@ -30,8 +30,8 @@
 #define NUM_BUFFERS 2
 
 struct SDL_PrivateAudioData {
-    /* The hardware output channel. */
-    int     channel;
+    /* The hardware input/output port. */
+    int     port;
     /* The raw allocated mixing buffer. */
     Uint8   *rawbuf;
     /* Individual mixing buffers. */

+ 4 - 0
Engine/lib/sdl/src/audio/wasapi/SDL_wasapi.c

@@ -558,12 +558,16 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
         return WIN_SetErrorFromHRESULT("WASAPI can't determine minimum device period", ret);
     }
 
+#if 1  /* we're getting reports that WASAPI's resampler introduces distortions, so it's disabled for now. --ryan. */
+    this->spec.freq = waveformat->nSamplesPerSec;  /* force sampling rate so our resampler kicks in, if necessary. */
+#else
     /* favor WASAPI's resampler over our own */
     if (this->spec.freq != waveformat->nSamplesPerSec) {
         streamflags |= (AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM | AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY);
         waveformat->nSamplesPerSec = this->spec.freq;
         waveformat->nAvgBytesPerSec = waveformat->nSamplesPerSec * waveformat->nChannels * (waveformat->wBitsPerSample / 8);
     }
+#endif
 
     streamflags |= AUDCLNT_STREAMFLAGS_EVENTCALLBACK;
     ret = IAudioClient_Initialize(client, sharemode, streamflags, 0, 0, waveformat, NULL);

+ 4 - 4
Engine/lib/sdl/src/core/linux/SDL_fcitx.c

@@ -339,11 +339,11 @@ SDL_Fcitx_Reset(void)
 }
 
 SDL_bool
-SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
+SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state)
 {
-    Uint32 state = Fcitx_ModState();
+    Uint32 mod_state = Fcitx_ModState();
     Uint32 handled = SDL_FALSE;
-    Uint32 is_release = SDL_FALSE;
+    Uint32 is_release = (state == SDL_RELEASED);
     Uint32 event_time = 0;
 
     if (!fcitx_client.ic_path) {
@@ -351,7 +351,7 @@ SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
     }
 
     if (SDL_DBus_CallMethod(FCITX_DBUS_SERVICE, fcitx_client.ic_path, FCITX_IC_DBUS_INTERFACE, "ProcessKeyEvent",
-            DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &keycode, DBUS_TYPE_UINT32, &state, DBUS_TYPE_BOOLEAN, &is_release, DBUS_TYPE_UINT32, &event_time, DBUS_TYPE_INVALID,
+            DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &keycode, DBUS_TYPE_UINT32, &mod_state, DBUS_TYPE_BOOLEAN, &is_release, DBUS_TYPE_UINT32, &event_time, DBUS_TYPE_INVALID,
             DBUS_TYPE_BOOLEAN, &handled, DBUS_TYPE_INVALID)) {
         if (handled) {
             SDL_Fcitx_UpdateTextRect(NULL);

+ 1 - 1
Engine/lib/sdl/src/core/linux/SDL_fcitx.h

@@ -31,7 +31,7 @@ extern SDL_bool SDL_Fcitx_Init(void);
 extern void SDL_Fcitx_Quit(void);
 extern void SDL_Fcitx_SetFocus(SDL_bool focused);
 extern void SDL_Fcitx_Reset(void);
-extern SDL_bool SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode);
+extern SDL_bool SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state);
 extern void SDL_Fcitx_UpdateTextRect(SDL_Rect *rect);
 extern void SDL_Fcitx_PumpEvents(void);
 

+ 8 - 3
Engine/lib/sdl/src/core/linux/SDL_ibus.c

@@ -503,15 +503,20 @@ SDL_IBus_Reset(void)
 }
 
 SDL_bool
-SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
+SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state)
 { 
     Uint32 result = 0;
     SDL_DBusContext *dbus = SDL_DBus_GetContext();
-    
+
+
     if (IBus_CheckConnection(dbus)) {
         Uint32 mods = IBus_ModState();
+        Uint32 ibus_keycode = keycode - 8;
+        if (state == SDL_RELEASED) {
+            mods |= (1 << 30); // IBUS_RELEASE_MASK
+        }
         if (!SDL_DBus_CallMethodOnConnection(ibus_conn, IBUS_SERVICE, input_ctx_path, IBUS_INPUT_INTERFACE, "ProcessKeyEvent",
-                DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &keycode, DBUS_TYPE_UINT32, &mods, DBUS_TYPE_INVALID,
+                DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &ibus_keycode, DBUS_TYPE_UINT32, &mods, DBUS_TYPE_INVALID,
                 DBUS_TYPE_BOOLEAN, &result, DBUS_TYPE_INVALID)) {
             result = 0;
         }

+ 1 - 1
Engine/lib/sdl/src/core/linux/SDL_ibus.h

@@ -41,7 +41,7 @@ extern void SDL_IBus_Reset(void);
 /* Sends a keypress event to IBus, returns SDL_TRUE if IBus used this event to
    update its candidate list or change input methods. PumpEvents should be
    called some time after this, to recieve the TextInput / TextEditing event back. */
-extern SDL_bool SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode);
+extern SDL_bool SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state);
 
 /* Update the position of IBus' candidate list. If rect is NULL then this will 
    just reposition it relative to the focused window's new position. */

+ 3 - 3
Engine/lib/sdl/src/core/linux/SDL_ime.c

@@ -27,7 +27,7 @@ typedef SDL_bool (*_SDL_IME_Init)(void);
 typedef void (*_SDL_IME_Quit)(void);
 typedef void (*_SDL_IME_SetFocus)(SDL_bool);
 typedef void (*_SDL_IME_Reset)(void);
-typedef SDL_bool (*_SDL_IME_ProcessKeyEvent)(Uint32, Uint32);
+typedef SDL_bool (*_SDL_IME_ProcessKeyEvent)(Uint32, Uint32, Uint8 state);
 typedef void (*_SDL_IME_UpdateTextRect)(SDL_Rect *);
 typedef void (*_SDL_IME_PumpEvents)(void);
 
@@ -127,10 +127,10 @@ SDL_IME_Reset(void)
 }
 
 SDL_bool
-SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
+SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state)
 {
     if (SDL_IME_ProcessKeyEvent_Real)
-        return SDL_IME_ProcessKeyEvent_Real(keysym, keycode);
+        return SDL_IME_ProcessKeyEvent_Real(keysym, keycode, state);
 
     return SDL_FALSE;
 }

+ 1 - 1
Engine/lib/sdl/src/core/linux/SDL_ime.h

@@ -31,7 +31,7 @@ extern SDL_bool SDL_IME_Init(void);
 extern void SDL_IME_Quit(void);
 extern void SDL_IME_SetFocus(SDL_bool focused);
 extern void SDL_IME_Reset(void);
-extern SDL_bool SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode);
+extern SDL_bool SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state);
 extern void SDL_IME_UpdateTextRect(SDL_Rect *rect);
 extern void SDL_IME_PumpEvents(void);
 

+ 73 - 46
Engine/lib/sdl/src/core/windows/SDL_windows.c

@@ -25,7 +25,15 @@
 #include "SDL_windows.h"
 #include "SDL_error.h"
 
-#include <objbase.h>  /* for CoInitialize/CoUninitialize (Win32 only) */
+#include <objbase.h>    /* for CoInitialize/CoUninitialize (Win32 only) */
+#if defined(HAVE_ROAPI_H)
+#include <roapi.h>      /* For RoInitialize/RoUninitialize (Win32 only) */
+#else
+typedef enum RO_INIT_TYPE {
+  RO_INIT_SINGLETHREADED = 0,
+  RO_INIT_MULTITHREADED  = 1
+} RO_INIT_TYPE;
+#endif
 
 #ifndef _WIN32_WINNT_VISTA
 #define _WIN32_WINNT_VISTA  0x0600
@@ -37,6 +45,10 @@
 #define _WIN32_WINNT_WIN8   0x0602
 #endif
 
+#ifndef LOAD_LIBRARY_SEARCH_SYSTEM32
+#define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
+#endif
+
 
 /* Sets an error message based on an HRESULT */
 int
@@ -104,51 +116,66 @@ void
 WIN_CoUninitialize(void)
 {
 #ifndef __WINRT__
-    /* Don't uninitialize COM because of what appears to be a bug in Microsoft WGI reference counting.
-     *
-     * If you plug in a non-Xbox controller and let the application run for 30 seconds, then it crashes in CoUninitialize()
-     * with this stack trace:
-
-        Windows.Gaming.Input.dll!GameController::~GameController(void)	Unknown
-        Windows.Gaming.Input.dll!GameController::`vector deleting destructor'(unsigned int)	Unknown
-        Windows.Gaming.Input.dll!Microsoft::WRL::Details::RuntimeClassImpl<struct Microsoft::WRL::RuntimeClassFlags<1>,1,1,0,struct Windows::Gaming::Input::IGameController,struct Windows::Gaming::Input::IGameControllerBatteryInfo,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Internal::IGameControllerPrivate>,class Microsoft::WRL::FtmBase>::Release(void)	Unknown
-        Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::AggregableRuntimeClass<struct Windows::Gaming::Input::IGamepad,struct Windows::Gaming::Input::IGamepad2,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::IGameControllerInputSink>,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::IGipGameControllerInputSink>,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::IHidGameControllerInputSink>,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::IXusbGameControllerInputSink>,class Microsoft::WRL::Details::Nil,class Microsoft::WRL::Details::Nil,class Microsoft::WRL::Details::Nil>::Release(void)	Unknown
-        Windows.Gaming.Input.dll!Microsoft::WRL::ComPtr<`WaitForCompletion<Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<Windows::Storage::Streams::IBuffer *,unsigned int>,Windows::Foundation::IAsyncOperationWithProgress<Windows::Storage::Streams::IBuffer *,unsigned int>>'::`2'::FTMEventDelegate>::~ComPtr<`WaitForCompletion<Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<Windows::Storage::Streams::IBuffer *,unsigned int>,Windows::Foundation::IAsyncOperationWithProgress<Windows::Storage::Streams::IBuffer *,unsigned int>>'::`2'::FTMEventDelegate>()	Unknown
-        Windows.Gaming.Input.dll!`eh vector destructor iterator'(void *,unsigned int,int,void (*)(void *))	Unknown
-        Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::GameControllerCollection<class Windows::Gaming::Input::RawGameController,struct Windows::Gaming::Input::IRawGameController>::~GameControllerCollection<class Windows::Gaming::Input::RawGameController,struct Windows::Gaming::Input::IRawGameController>(void)	Unknown
-        Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::GameControllerCollection<class Windows::Gaming::Input::RawGameController,struct Windows::Gaming::Input::IRawGameController>::`vector deleting destructor'(unsigned int)	Unknown
-        Windows.Gaming.Input.dll!Microsoft::WRL::Details::RuntimeClassImpl<struct Microsoft::WRL::RuntimeClassFlags<1>,1,1,0,struct Windows::Foundation::Collections::IIterable<class Windows::Gaming::Input::ArcadeStick *>,struct Windows::Foundation::Collections::IVectorView<class Windows::Gaming::Input::ArcadeStick *>,class Microsoft::WRL::FtmBase>::Release(void)	Unknown
-        Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::CustomGameControllerFactoryBase<class Windows::Gaming::Input::FlightStick,class Windows::Gaming::Input::FlightStick,struct Windows::Gaming::Input::IFlightStick,struct Windows::Gaming::Input::IFlightStickStatics,class Microsoft::WRL::Details::Nil>::~CustomGameControllerFactoryBase<class Windows::Gaming::Input::FlightStick,class Windows::Gaming::Input::FlightStick,struct Windows::Gaming::Input::IFlightStick,struct Windows::Gaming::Input::IFlightStickStatics,class Microsoft::WRL::Details::Nil>(void)	Unknown
-        Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::CustomGameControllerFactoryBase<class Windows::Gaming::Input::FlightStick,class Windows::Gaming::Input::FlightStick,struct Windows::Gaming::Input::IFlightStick,struct Windows::Gaming::Input::IFlightStickStatics,class Microsoft::WRL::Details::Nil>::`vector deleting destructor'(unsigned int)	Unknown
-        Windows.Gaming.Input.dll!Microsoft::WRL::ActivationFactory<struct Microsoft::WRL::Implements<class Microsoft::WRL::FtmBase,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::ICustomGameControllerFactory> >,struct Windows::Gaming::Input::IFlightStickStatics,class Microsoft::WRL::Details::Nil,0>::Release(void)	Unknown
-        Windows.Gaming.Input.dll!Microsoft::WRL::ComPtr<`WaitForCompletion<Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<Windows::Storage::Streams::IBuffer *,unsigned int>,Windows::Foundation::IAsyncOperationWithProgress<Windows::Storage::Streams::IBuffer *,unsigned int>>'::`2'::FTMEventDelegate>::~ComPtr<`WaitForCompletion<Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<Windows::Storage::Streams::IBuffer *,unsigned int>,Windows::Foundation::IAsyncOperationWithProgress<Windows::Storage::Streams::IBuffer *,unsigned int>>'::`2'::FTMEventDelegate>()	Unknown
-        Windows.Gaming.Input.dll!NtList<struct FactoryManager::FactoryListEntry>::~NtList<struct FactoryManager::FactoryListEntry>(void)	Unknown
-        Windows.Gaming.Input.dll!FactoryManager::`vector deleting destructor'(unsigned int)	Unknown
-        Windows.Gaming.Input.dll!Microsoft::WRL::ActivationFactory<struct Microsoft::WRL::Implements<class Microsoft::WRL::FtmBase,struct Windows::Gaming::Input::Custom::IGameControllerFactoryManagerStatics>,struct Windows::Gaming::Input::Custom::IGameControllerFactoryManagerStatics2,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Internal::IGameControllerFactoryManagerStaticsPrivate>,0>::Release(void)	Unknown
-        Windows.Gaming.Input.dll!Microsoft::WRL::Details::TerminateMap(class Microsoft::WRL::Details::ModuleBase *,unsigned short const *,bool)	Unknown
-        Windows.Gaming.Input.dll!Microsoft::WRL::Module<1,class Microsoft::WRL::Details::DefaultModule<1> >::~Module<1,class Microsoft::WRL::Details::DefaultModule<1> >(void)	Unknown
-        Windows.Gaming.Input.dll!Microsoft::WRL::Details::DefaultModule<1>::`vector deleting destructor'(unsigned int)	Unknown
-        Windows.Gaming.Input.dll!`dynamic atexit destructor for 'Microsoft::WRL::Details::StaticStorage<Microsoft::WRL::Details::DefaultModule<1>,0,int>::instance_''()	Unknown
-        Windows.Gaming.Input.dll!__CRT_INIT@12()	Unknown
-        Windows.Gaming.Input.dll!__DllMainCRTStartup()	Unknown
-        ntdll.dll!_LdrxCallInitRoutine@16()	Unknown
-        ntdll.dll!LdrpCallInitRoutine()	Unknown
-        ntdll.dll!LdrpProcessDetachNode()	Unknown
-        ntdll.dll!LdrpUnloadNode()	Unknown
-        ntdll.dll!LdrpDecrementModuleLoadCountEx()	Unknown
-        ntdll.dll!LdrUnloadDll()	Unknown
-        KernelBase.dll!FreeLibrary()	Unknown
-        combase.dll!FreeLibraryWithLogging(LoadOrFreeWhy why, HINSTANCE__ * hMod, const wchar_t * pswzOptionalFileName) Line 193	C++
-        combase.dll!CClassCache::CDllPathEntry::CFinishObject::Finish() Line 3311	C++
-        combase.dll!CClassCache::CFinishComposite::Finish() Line 3421	C++
-        combase.dll!CClassCache::CleanUpDllsForProcess() Line 7009	C++
-        [Inline Frame] combase.dll!CCCleanUpDllsForProcess() Line 8773	C++
-        combase.dll!ProcessUninitialize() Line 2243	C++
-        combase.dll!DecrementProcessInitializeCount() Line 993	C++
-        combase.dll!wCoUninitialize(COleTls & Tls, int fHostThread) Line 4126	C++
-        combase.dll!CoUninitialize() Line 3945	C++
-    */
-    /*CoUninitialize();*/
+    CoUninitialize();
+#endif
+}
+
+#ifndef __WINRT__
+void *
+WIN_LoadComBaseFunction(const char *name)
+{
+    static SDL_bool s_bLoaded;
+    static HMODULE s_hComBase;
+   
+    if (!s_bLoaded) {
+       s_hComBase = LoadLibraryEx(TEXT("combase.dll"), NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
+       s_bLoaded = SDL_TRUE;
+    }
+    if (s_hComBase) {
+        return GetProcAddress(s_hComBase, name);
+    } else {
+        return NULL;
+    }
+}
+#endif
+
+HRESULT
+WIN_RoInitialize(void)
+{
+#ifdef __WINRT__
+    return S_OK;
+#else
+    typedef HRESULT (WINAPI *RoInitialize_t)(RO_INIT_TYPE initType);
+    RoInitialize_t RoInitializeFunc = (RoInitialize_t)WIN_LoadComBaseFunction("RoInitialize");
+    if (RoInitializeFunc) {
+        /* RO_INIT_SINGLETHREADED is equivalent to COINIT_APARTMENTTHREADED */
+        HRESULT hr = RoInitializeFunc(RO_INIT_SINGLETHREADED);
+        if (hr == RPC_E_CHANGED_MODE) {
+            hr = RoInitializeFunc(RO_INIT_MULTITHREADED);
+        }
+
+        /* S_FALSE means success, but someone else already initialized. */
+        /* You still need to call RoUninitialize in this case! */
+        if (hr == S_FALSE) {
+            return S_OK;
+        }
+
+        return hr;
+    } else {
+        return E_NOINTERFACE;
+    }
+#endif
+}
+
+void
+WIN_RoUninitialize(void)
+{
+#ifndef __WINRT__
+    typedef void (WINAPI *RoUninitialize_t)(void);
+    RoUninitialize_t RoUninitializeFunc = (RoUninitialize_t)WIN_LoadComBaseFunction("RoUninitialize");
+    if (RoUninitializeFunc) {
+        RoUninitializeFunc();
+    }
 #endif
 }
 

+ 9 - 0
Engine/lib/sdl/src/core/windows/SDL_windows.h

@@ -63,10 +63,19 @@ extern int WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr);
 /* Sets an error message based on GetLastError(). Always return -1. */
 extern int WIN_SetError(const char *prefix);
 
+#if !defined(__WINRT__)
+/* Load a function from combase.dll */
+void *WIN_LoadComBaseFunction(const char *name);
+#endif
+
 /* Wrap up the oddities of CoInitialize() into a common function. */
 extern HRESULT WIN_CoInitialize(void);
 extern void WIN_CoUninitialize(void);
 
+/* Wrap up the oddities of RoInitialize() into a common function. */
+extern HRESULT WIN_RoInitialize(void);
+extern void WIN_RoUninitialize(void);
+
 /* Returns SDL_TRUE if we're running on Windows Vista and newer */
 extern BOOL WIN_IsWindowsVistaOrGreater(void);
 

+ 1 - 0
Engine/lib/sdl/src/dynapi/SDL_dynapi_overrides.h

@@ -864,3 +864,4 @@
 #define SDL_UnionFRect SDL_UnionFRect_REAL
 #define SDL_EncloseFPoints SDL_EncloseFPoints_REAL
 #define SDL_IntersectFRectAndLine SDL_IntersectFRectAndLine_REAL
+#define SDL_RenderGetWindow SDL_RenderGetWindow_REAL

+ 1 - 0
Engine/lib/sdl/src/dynapi/SDL_dynapi_procs.h

@@ -935,3 +935,4 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_IntersectFRect,(const SDL_FRect *a, const SDL_FRect
 SDL_DYNAPI_PROC(void,SDL_UnionFRect,(const SDL_FRect *a, const SDL_FRect *b, SDL_FRect *c),(a,b,c),)
 SDL_DYNAPI_PROC(SDL_bool,SDL_EncloseFPoints,(const SDL_FPoint *a, int b, const SDL_FRect *c, SDL_FRect *d),(a,b,c,d),return)
 SDL_DYNAPI_PROC(SDL_bool,SDL_IntersectFRectAndLine,(const SDL_FRect *a, float *b, float *c, float *d, float *e),(a,b,c,d,e),return)
+SDL_DYNAPI_PROC(SDL_Window*,SDL_RenderGetWindow,(SDL_Renderer *a),(a),return)

+ 1 - 0
Engine/lib/sdl/src/events/SDL_keyboard.c

@@ -638,6 +638,7 @@ SDL_SetKeyboardFocus(SDL_Window * window)
         /* old window must lose an existing mouse capture. */
         if (keyboard->focus->flags & SDL_WINDOW_MOUSE_CAPTURE) {
             SDL_CaptureMouse(SDL_FALSE);  /* drop the capture. */
+            SDL_UpdateMouseCapture(SDL_TRUE);
             SDL_assert(!(keyboard->focus->flags & SDL_WINDOW_MOUSE_CAPTURE));
         }
 

+ 72 - 33
Engine/lib/sdl/src/events/SDL_mouse.c

@@ -109,6 +109,28 @@ SDL_TouchMouseEventsChanged(void *userdata, const char *name, const char *oldVal
     mouse->touch_mouse_events = SDL_GetStringBoolean(hint, SDL_TRUE);
 }
 
+#if defined(__vita__)
+static void SDLCALL
+SDL_VitaTouchMouseDeviceChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
+{
+    SDL_Mouse *mouse = (SDL_Mouse *)userdata;
+    if (hint) {
+        switch(*hint) {
+        default:
+        case '0':
+            mouse->vita_touch_mouse_device = 0;
+            break;
+        case '1':
+            mouse->vita_touch_mouse_device = 1;
+            break;
+        case '2':
+            mouse->vita_touch_mouse_device = 2;
+            break;
+        }
+    }
+}
+#endif
+
 static void SDLCALL
 SDL_MouseTouchEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
 {
@@ -134,12 +156,8 @@ SDL_MouseAutoCaptureChanged(void *userdata, const char *name, const char *oldVal
     SDL_bool auto_capture = SDL_GetStringBoolean(hint, SDL_TRUE);
 
     if (auto_capture != mouse->auto_capture) {
-        /* Turn off mouse capture if it's currently active because of button presses */
-        if (!auto_capture && SDL_GetMouseState(NULL, NULL) != 0) {
-            SDL_CaptureMouse(SDL_FALSE);
-        }
-
         mouse->auto_capture = auto_capture;
+        SDL_UpdateMouseCapture(SDL_FALSE);
     }
 }
 
@@ -166,6 +184,11 @@ SDL_MouseInit(void)
     SDL_AddHintCallback(SDL_HINT_TOUCH_MOUSE_EVENTS,
                         SDL_TouchMouseEventsChanged, mouse);
 
+#if defined(__vita__)
+    SDL_AddHintCallback(SDL_HINT_VITA_TOUCH_MOUSE_DEVICE,
+                        SDL_VitaTouchMouseDeviceChanged, mouse);
+#endif
+
     SDL_AddHintCallback(SDL_HINT_MOUSE_TOUCH_EVENTS,
                         SDL_MouseTouchEventsChanged, mouse);
 
@@ -384,12 +407,9 @@ SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relativ
 
     /* Ignore relative motion when first positioning the mouse */
     if (!mouse->has_position) {
-        xrel = 0;
-        yrel = 0;
         mouse->x = x;
         mouse->y = y;
         mouse->has_position = SDL_TRUE;
-        return 0;
     } else if (!xrel && !yrel) {  /* Drop events that don't change state */
 #ifdef DEBUG_MOUSE
         SDL_Log("Mouse event didn't change state - dropped!\n");
@@ -540,7 +560,6 @@ SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state
     Uint32 type;
     Uint32 buttonstate;
     SDL_MouseInputSource *source;
-    SDL_bool had_buttons_pressed = (SDL_GetMouseState(NULL, NULL) ? SDL_TRUE : SDL_FALSE);
 
     source = GetMouseInputSource(mouse, mouseID);
     if (!source) {
@@ -643,10 +662,7 @@ SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state
 
     /* Automatically capture the mouse while buttons are pressed */
     if (mouse->auto_capture) {
-        SDL_bool has_buttons_pressed = (SDL_GetMouseState(NULL, NULL) ? SDL_TRUE : SDL_FALSE);
-        if (has_buttons_pressed != had_buttons_pressed) {
-            SDL_CaptureMouse(has_buttons_pressed);
-        }
+        SDL_UpdateMouseCapture(SDL_FALSE);
     }
 
     return posted;
@@ -743,6 +759,7 @@ SDL_MouseQuit(void)
 
     if (mouse->CaptureMouse) {
         SDL_CaptureMouse(SDL_FALSE);
+        SDL_UpdateMouseCapture(SDL_TRUE);
     }
     SDL_SetRelativeMouseMode(SDL_FALSE);
     SDL_ShowCursor(1);
@@ -947,6 +964,8 @@ SDL_SetRelativeMouseMode(SDL_bool enabled)
         if (!enabled) {
             SDL_WarpMouseInWindow(focusWindow, mouse->x, mouse->y);
         }
+
+        SDL_UpdateMouseCapture(SDL_FALSE);
     }
 
     if (!enabled) {
@@ -969,40 +988,60 @@ SDL_GetRelativeMouseMode()
 }
 
 int
-SDL_CaptureMouse(SDL_bool enabled)
+SDL_UpdateMouseCapture(SDL_bool force_release)
 {
     SDL_Mouse *mouse = SDL_GetMouse();
-    SDL_Window *focusWindow;
-    SDL_bool isCaptured;
+    SDL_Window *capture_window = NULL;
 
     if (!mouse->CaptureMouse) {
-        return SDL_Unsupported();
+        return 0;
     }
 
-    focusWindow = SDL_GetKeyboardFocus();
-
-    isCaptured = focusWindow && (focusWindow->flags & SDL_WINDOW_MOUSE_CAPTURE);
-    if (isCaptured == enabled) {
-        return 0;  /* already done! */
+    if (!force_release) {
+        if (mouse->capture_desired || (mouse->auto_capture && SDL_GetMouseState(NULL, NULL) != 0)) {
+            if (!mouse->relative_mode) {
+                capture_window = SDL_GetKeyboardFocus();
+            }
+        }
     }
 
-    if (enabled) {
-        if (!focusWindow) {
-            return SDL_SetError("No window has focus");
-        } else if (mouse->CaptureMouse(focusWindow) == -1) {
-            return -1;  /* CaptureMouse() should call SetError */
+    if (capture_window != mouse->capture_window) {
+        if (mouse->capture_window) {
+            mouse->CaptureMouse(NULL);
+            mouse->capture_window->flags &= ~SDL_WINDOW_MOUSE_CAPTURE;
+            mouse->capture_window = NULL;
         }
-        focusWindow->flags |= SDL_WINDOW_MOUSE_CAPTURE;
-    } else {
-        if (mouse->CaptureMouse(NULL) == -1) {
-            return -1;  /* CaptureMouse() should call SetError */
+
+        if (capture_window) {
+            if (mouse->CaptureMouse(capture_window) < 0) {
+                /* CaptureMouse() will have set an error */
+                return -1;
+            }
+            capture_window->flags |= SDL_WINDOW_MOUSE_CAPTURE;
         }
-        focusWindow->flags &= ~SDL_WINDOW_MOUSE_CAPTURE;
-    }
 
+        mouse->capture_window = capture_window;
+    }
     return 0;
 }
 
+int
+SDL_CaptureMouse(SDL_bool enabled)
+{
+    SDL_Mouse *mouse = SDL_GetMouse();
+
+    if (!mouse->CaptureMouse) {
+        return SDL_Unsupported();
+    }
+
+    if (enabled && SDL_GetKeyboardFocus() == NULL) {
+        return SDL_SetError("No window has focus");
+    }
+    mouse->capture_desired = enabled;
+
+    return SDL_UpdateMouseCapture(SDL_FALSE);
+}
+
 SDL_Cursor *
 SDL_CreateCursor(const Uint8 * data, const Uint8 * mask,
                  int w, int h, int hot_x, int hot_y)

+ 8 - 0
Engine/lib/sdl/src/events/SDL_mouse_c.h

@@ -100,7 +100,12 @@ typedef struct
     SDL_bool touch_mouse_events;
     SDL_bool mouse_touch_events;
     SDL_bool was_touch_mouse_events; /* Was a touch-mouse event pending? */
+#if defined(__vita__)
+    Uint8 vita_touch_mouse_device;
+#endif
     SDL_bool auto_capture;
+    SDL_bool capture_desired;
+    SDL_Window *capture_window;
 
     /* Data for input source state */
     int num_sources;
@@ -132,6 +137,9 @@ extern void SDL_SetDefaultCursor(SDL_Cursor * cursor);
 /* Set the mouse focus window */
 extern void SDL_SetMouseFocus(SDL_Window * window);
 
+/* Update the mouse capture window */
+extern int SDL_UpdateMouseCapture(SDL_bool force_release);
+
 /* Send a mouse motion event */
 extern int SDL_SendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y);
 

+ 5 - 0
Engine/lib/sdl/src/events/SDL_touch.c

@@ -265,8 +265,13 @@ SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window * window,
 
 #if SYNTHESIZE_TOUCH_TO_MOUSE
     /* SDL_HINT_TOUCH_MOUSE_EVENTS: controlling whether touch events should generate synthetic mouse events */
+    /* SDL_HINT_VITA_TOUCH_MOUSE_DEVICE: controlling which touchpad should generate synthetic mouse events, PSVita-only */
     {
+#if defined(__vita__)
+        if (mouse->touch_mouse_events && ((mouse->vita_touch_mouse_device == id) || (mouse->vita_touch_mouse_device == 2)) ) {
+#else
         if (mouse->touch_mouse_events) {
+#endif
             /* FIXME: maybe we should only restrict to a few SDL_TouchDeviceType */
             if (id != SDL_MOUSE_TOUCHID) {
                 if (window) {

+ 1 - 19
Engine/lib/sdl/src/filesystem/windows/SDL_sysfilesystem.c

@@ -35,39 +35,23 @@
 char *
 SDL_GetBasePath(void)
 {
-    typedef DWORD (WINAPI *GetModuleFileNameExW_t)(HANDLE, HMODULE, LPWSTR, DWORD);
-    GetModuleFileNameExW_t pGetModuleFileNameExW;
     DWORD buflen = 128;
     WCHAR *path = NULL;
-    HANDLE psapi = LoadLibrary(TEXT("psapi.dll"));
     char *retval = NULL;
     DWORD len = 0;
     int i;
 
-    if (!psapi) {
-        WIN_SetError("Couldn't load psapi.dll");
-        return NULL;
-    }
-
-    pGetModuleFileNameExW = (GetModuleFileNameExW_t)GetProcAddress(psapi, "GetModuleFileNameExW");
-    if (!pGetModuleFileNameExW) {
-        WIN_SetError("Couldn't find GetModuleFileNameExW");
-        FreeLibrary(psapi);
-        return NULL;
-    }
-
     while (SDL_TRUE) {
         void *ptr = SDL_realloc(path, buflen * sizeof (WCHAR));
         if (!ptr) {
             SDL_free(path);
-            FreeLibrary(psapi);
             SDL_OutOfMemory();
             return NULL;
         }
 
         path = (WCHAR *) ptr;
 
-        len = pGetModuleFileNameExW(GetCurrentProcess(), NULL, path, buflen);
+        len = GetModuleFileNameW(NULL, path, buflen);
         /* if it truncated, then len >= buflen - 1 */
         /* if there was enough room (or failure), len < buflen - 1 */
         if (len < buflen - 1) {
@@ -78,8 +62,6 @@ SDL_GetBasePath(void)
         buflen *= 2;
     }
 
-    FreeLibrary(psapi);
-
     if (len == 0) {
         SDL_free(path);
         WIN_SetError("Couldn't locate our .exe");

+ 6 - 4
Engine/lib/sdl/src/hidapi/SDL_hidapi.c

@@ -951,6 +951,7 @@ DeleteHIDDeviceWrapper(SDL_hid_device *device)
     }
 
 #if !SDL_HIDAPI_DISABLED
+#if HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || defined(SDL_LIBUSB_DYNAMIC)
 
 #define COPY_IF_EXISTS(var) \
     if (pSrc->var != NULL) { \
@@ -987,6 +988,7 @@ CopyHIDDeviceInfo(struct SDL_hid_device_info *pSrc, struct SDL_hid_device_info *
 #undef COPY_IF_EXISTS
 #undef WCOPY_IF_EXISTS
 
+#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || SDL_LIBUSB_DYNAMIC */
 #endif /* !SDL_HIDAPI_DISABLED */
 
 static int SDL_hidapi_refcount = 0;
@@ -1185,9 +1187,9 @@ struct SDL_hid_device_info *SDL_hid_enumerate(unsigned short vendor_id, unsigned
 #ifdef SDL_LIBUSB_DYNAMIC
     if (libusb_ctx.libhandle) {
         usb_devs = LIBUSB_hid_enumerate(vendor_id, product_id);
-  #ifdef DEBUG_HIDAPI
+#ifdef DEBUG_HIDAPI
         SDL_Log("libusb devices found:");
-  #endif
+#endif
         for (usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next) {
             new_dev = (struct SDL_hid_device_info*) SDL_malloc(sizeof(struct SDL_hid_device_info));
             if (!new_dev) {
@@ -1197,11 +1199,11 @@ struct SDL_hid_device_info *SDL_hid_enumerate(unsigned short vendor_id, unsigned
                 return NULL;
             }
             CopyHIDDeviceInfo(usb_dev, new_dev);
-  #ifdef DEBUG_HIDAPI
+#ifdef DEBUG_HIDAPI
             SDL_Log(" - %ls %ls 0x%.4hx 0x%.4hx",
                     usb_dev->manufacturer_string, usb_dev->product_string,
                     usb_dev->vendor_id, usb_dev->product_id);
-  #endif
+#endif
 
             if (last != NULL) {
                 last->next = new_dev;

+ 1 - 0
Engine/lib/sdl/src/hidapi/libusb/hid.c

@@ -1497,6 +1497,7 @@ void HID_API_EXPORT hid_close(hid_device *dev)
 
 	/* Clean up the Transfer objects allocated in read_thread(). */
 	free(dev->transfer->buffer);
+	dev->transfer->buffer = NULL;
 	libusb_free_transfer(dev->transfer);
 
 	/* release the interface */

+ 12 - 10
Engine/lib/sdl/src/hidapi/mac/hid.c

@@ -572,8 +572,7 @@ struct hid_device_info  HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
 		if ((vendor_id == 0x0 && product_id == 0x0) ||
 		    (vendor_id == dev_vid && product_id == dev_pid)) {
 			struct hid_device_info *tmp;
-			size_t len;
-			
+
 			/* VID/PID match. Create the record. */
 			tmp = (struct hid_device_info *)calloc(1, sizeof(struct hid_device_info));
 			if (cur_dev) {
@@ -590,7 +589,7 @@ struct hid_device_info  HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
 			
 			/* Fill out the record */
 			cur_dev->next = NULL;
-			len = make_path(dev, cbuf, sizeof(cbuf));
+			make_path(dev, cbuf, sizeof(cbuf));
 			cur_dev->path = strdup(cbuf);
 			
 			/* Serial Number */
@@ -817,10 +816,9 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive)
 	CFSetGetValues(device_set, (const void **) device_array);	
 	for (i = 0; i < num_devices; i++) {
 		char cbuf[BUF_LEN];
-		size_t len;
 		IOHIDDeviceRef os_dev = device_array[i];
 		
-		len = make_path(os_dev, cbuf, sizeof(cbuf));
+		make_path(os_dev, cbuf, sizeof(cbuf));
 		if (!strcmp(cbuf, path)) {
 			// Matched Paths. Open this Device.
 			IOReturn ret = IOHIDDeviceOpen(os_dev, kIOHIDOptionsTypeNone);
@@ -833,6 +831,7 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive)
 				
 				/* Create the buffers for receiving data */
 				dev->max_input_report_len = (CFIndex) get_max_report_length(os_dev);
+				SDL_assert(dev->max_input_report_len > 0);
 				dev->input_report_buf = (uint8_t *)calloc(dev->max_input_report_len, sizeof(uint8_t));
 				
 				/* Create the Run Loop Mode for this device.
@@ -936,11 +935,14 @@ static int return_data(hid_device *dev, unsigned char *data, size_t length)
 	/* Copy the data out of the linked list item (rpt) into the
 	 return buffer (data), and delete the liked list item. */
 	struct input_report *rpt = dev->input_reports;
-	size_t len = (length < rpt->len)? length: rpt->len;
-	memcpy(data, rpt->data, len);
-	dev->input_reports = rpt->next;
-	free(rpt->data);
-	free(rpt);
+	size_t len = 0;
+	if (rpt != NULL) {
+		len = (length < rpt->len)? length: rpt->len;
+		memcpy(data, rpt->data, len);
+		dev->input_reports = rpt->next;
+		free(rpt->data);
+		free(rpt);
+	}
 	return (int)len;
 }
 

+ 2 - 1
Engine/lib/sdl/src/joystick/SDL_gamecontrollerdb.h

@@ -501,7 +501,7 @@ static const char *s_ControllerMappings [] =
     "03000000830500006020000000010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
     "03000000830500006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,",
 #endif
-#if defined(__LINUX__)
+#ifdef SDL_JOYSTICK_LINUX
     "xinput,*,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
     "03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
     "03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
@@ -762,6 +762,7 @@ static const char *s_ControllerMappings [] =
     "0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,",
     "030000004f0400000ed0000011010000,ThrustMaster eSwap PRO Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
     "030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,",
+    "030000004f04000015b3000001010000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,",
     "030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,",
     "030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
     "030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,",

+ 9 - 4
Engine/lib/sdl/src/joystick/SDL_joystick.c

@@ -1590,11 +1590,13 @@ SDL_JoystickUpdate(void)
 
     for (joystick = SDL_joysticks; joystick; joystick = joystick->next) {
         if (joystick->attached) {
-            /* This should always be true, but seeing a crash in the wild...? */
-            if (joystick->driver) {
-                joystick->driver->Update(joystick);
+            /* This driver should always be != NULL, but seeing a crash in the wild...? */
+            if (!joystick->driver) {
+                continue;  /* nothing we can do, and other things use joystick->driver below here. */
             }
 
+            joystick->driver->Update(joystick);
+
             if (joystick->delayed_guide_button) {
                 SDL_GameControllerHandleDelayedGuideButton(joystick);
             }
@@ -2158,7 +2160,10 @@ static SDL_bool SDL_IsJoystickProductWheel(Uint32 vidpid)
         MAKE_VIDPID(0x044f, 0xb65d),    /* Thrustmaster Wheel FFB */
         MAKE_VIDPID(0x044f, 0xb66d),    /* Thrustmaster Wheel FFB */
         MAKE_VIDPID(0x044f, 0xb677),    /* Thrustmaster T150 */
-        MAKE_VIDPID(0x044f, 0xb66e),    /* Thrustmaster T300RS */
+        MAKE_VIDPID(0x044f, 0xb696),    /* Thrustmaster T248 */
+        MAKE_VIDPID(0x044f, 0xb66e),    /* Thrustmaster T300RS (normal mode) */
+        MAKE_VIDPID(0x044f, 0xb66f),    /* Thrustmaster T300RS (advanced mode) */
+        MAKE_VIDPID(0x044f, 0xb66d),    /* Thrustmaster T300RS (PS4 mode) */
         MAKE_VIDPID(0x044f, 0xb65e),    /* Thrustmaster T500RS */
         MAKE_VIDPID(0x044f, 0xb664),    /* Thrustmaster TX (initial mode) */
         MAKE_VIDPID(0x044f, 0xb669),    /* Thrustmaster TX (active mode) */

+ 9 - 2
Engine/lib/sdl/src/joystick/hidapi/SDL_hidapi_ps5.c

@@ -747,7 +747,11 @@ HIDAPI_DriverPS5_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joy
         }
     }
 
-    return SDL_HIDAPI_SendRumbleAndUnlock(device, data, report_size);
+    if (SDL_HIDAPI_SendRumbleAndUnlock(device, data, report_size) != report_size) {
+        return -1;
+    }
+
+    return 0;
 }
 
 static int
@@ -957,7 +961,10 @@ HIDAPI_DriverPS5_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev,
     axis = ((int)packet->ucRightJoystickY * 257) - 32768;
     SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
 
-    if (packet->ucBatteryLevel & 0x10) {
+    /* A check of packet->ucBatteryLevel & 0x10 should work as a check for BT vs USB but doesn't
+     * seem to always work. Possibly related to being 100% charged?
+     */
+    if (!ctx->is_bluetooth) {
         /* 0x20 set means fully charged */
         SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_WIRED);
     } else {

+ 1 - 1
Engine/lib/sdl/src/joystick/hidapi/SDL_hidapijoystick.c

@@ -227,7 +227,7 @@ HIDAPI_CleanupDeviceDriver(SDL_HIDAPI_Device *device)
     }
 
     /* Disconnect any joysticks */
-    while (device->num_joysticks) {
+    while (device->num_joysticks && device->joysticks) {
         HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
     }
 

+ 13 - 0
Engine/lib/sdl/src/joystick/iphoneos/SDL_mfijoystick.m

@@ -330,6 +330,19 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle
             subtype = 1;
         }
 
+        if (SDL_strcmp(name, "Backbone One") == 0) {
+            /* The Backbone app uses the guide and share buttons */
+            if ((device->button_mask & (1 << SDL_CONTROLLER_BUTTON_GUIDE)) != 0) {
+                device->button_mask &= ~(1 << SDL_CONTROLLER_BUTTON_GUIDE);
+                --nbuttons;
+            }
+            if ((device->button_mask & (1 << SDL_CONTROLLER_BUTTON_MISC1)) != 0) {
+                device->button_mask &= ~(1 << SDL_CONTROLLER_BUTTON_MISC1);
+                --nbuttons;
+                device->has_xbox_share_button = SDL_FALSE;
+            }
+        }
+
         device->naxes = 6; /* 2 thumbsticks and 2 triggers */
         device->nhats = 1; /* d-pad */
         device->nbuttons = nbuttons;

+ 88 - 31
Engine/lib/sdl/src/joystick/linux/SDL_sysjoystick.c

@@ -109,6 +109,7 @@ typedef struct SDL_joylist_item
     /* Steam Controller support */
     SDL_bool m_bSteamController;
 
+    SDL_bool checked_mapping;
     SDL_GamepadMapping *mapping;
 } SDL_joylist_item;
 
@@ -605,6 +606,26 @@ LINUX_InotifyJoystickDetect(void)
 }
 #endif /* HAVE_INOTIFY */
 
+static int get_event_joystick_index(int event)
+{
+    int joystick_index = -1;
+    int i, count;
+    struct dirent **entries = NULL;
+    char path[PATH_MAX];
+
+    SDL_snprintf(path, SDL_arraysize(path), "/sys/class/input/event%d/device", event);
+    count = scandir(path, &entries, NULL, alphasort);
+    for (i = 0; i < count; ++i) {
+        if (SDL_strncmp(entries[i]->d_name, "js", 2) == 0) {
+            joystick_index = SDL_atoi(entries[i]->d_name+2);
+        }
+        free(entries[i]); /* This should NOT be SDL_free() */
+    }
+    free(entries); /* This should NOT be SDL_free() */
+
+    return joystick_index;
+}
+
 /* Detect devices by reading /dev/input. In the inotify code path we
  * have to do this the first time, to detect devices that already existed
  * before we started; in the non-inotify code path we do this repeatedly
@@ -615,12 +636,39 @@ filter_entries(const struct dirent *entry)
     return IsJoystickDeviceNode(entry->d_name);
 }
 static int
-sort_entries(const struct dirent **a, const struct dirent **b)
+sort_entries(const void *_a, const void *_b)
 {
-    int numA = SDL_atoi((*a)->d_name+5);
-    int numB = SDL_atoi((*b)->d_name+5);
+    const struct dirent **a = (const struct dirent **)_a;
+    const struct dirent **b = (const struct dirent **)_b;
+    int numA, numB;
+    int offset;
+
+    if (SDL_classic_joysticks) {
+        offset = 2; /* strlen("js") */
+        numA = SDL_atoi((*a)->d_name+offset);
+        numB = SDL_atoi((*b)->d_name+offset);
+    } else {
+        offset = 5; /* strlen("event") */
+        numA = SDL_atoi((*a)->d_name+offset);
+        numB = SDL_atoi((*b)->d_name+offset);
+
+        /* See if we can get the joystick ordering */
+        {
+            int jsA = get_event_joystick_index(numA);
+            int jsB = get_event_joystick_index(numB);
+            if (jsA >= 0 && jsB >= 0) {
+                numA = jsA;
+                numB = jsB;
+            } else if (jsA >= 0) {
+                return -1;
+            } else if (jsB >= 0) {
+                return 1;
+            }
+        }
+    }
     return (numA - numB);
 }
+
 static void
 LINUX_FallbackJoystickDetect(void)
 {
@@ -633,10 +681,13 @@ LINUX_FallbackJoystickDetect(void)
         /* Opening input devices can generate synchronous device I/O, so avoid it if we can */
         if (stat("/dev/input", &sb) == 0 && sb.st_mtime != last_input_dir_mtime) {
             int i, count;
-            struct dirent **entries;
+            struct dirent **entries = NULL;
             char path[PATH_MAX];
 
-            count = scandir("/dev/input", &entries, filter_entries, sort_entries);
+            count = scandir("/dev/input", &entries, filter_entries, NULL);
+            if (count > 1) {
+                qsort(entries, count, sizeof(*entries), sort_entries);
+            }
             for (i = 0; i < count; ++i) {
                 SDL_snprintf(path, SDL_arraysize(path), "/dev/input/%s", entries[i]->d_name);
                 MaybeAddDevice(path);
@@ -683,29 +734,7 @@ LINUX_JoystickInit(void)
 
     SDL_classic_joysticks = SDL_GetHintBoolean(SDL_HINT_LINUX_JOYSTICK_CLASSIC, SDL_FALSE);
 
-#if SDL_USE_LIBUDEV
-    if (enumeration_method == ENUMERATION_UNSET) {
-        if (SDL_GetHintBoolean("SDL_JOYSTICK_DISABLE_UDEV", SDL_FALSE)) {
-            SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
-                         "udev disabled by SDL_JOYSTICK_DISABLE_UDEV");
-            enumeration_method = ENUMERATION_FALLBACK;
-
-        } else if (access("/.flatpak-info", F_OK) == 0
-                 || access("/run/host/container-manager", F_OK) == 0) {
-            /* Explicitly check `/.flatpak-info` because, for old versions of
-             * Flatpak, this was the only available way to tell if we were in
-             * a Flatpak container. */
-            SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
-                         "Container detected, disabling udev integration");
-            enumeration_method = ENUMERATION_FALLBACK;
-
-        } else {
-            SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
-                         "Using udev for joystick device discovery");
-            enumeration_method = ENUMERATION_LIBUDEV;
-        }
-    }
-#endif
+    enumeration_method = ENUMERATION_UNSET;
 
     /* First see if the user specified one or more joysticks to use */
     if (devices != NULL) {
@@ -734,6 +763,28 @@ LINUX_JoystickInit(void)
     LINUX_JoystickDetect();
 
 #if SDL_USE_LIBUDEV
+    if (enumeration_method == ENUMERATION_UNSET) {
+        if (SDL_GetHintBoolean("SDL_JOYSTICK_DISABLE_UDEV", SDL_FALSE)) {
+            SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
+                         "udev disabled by SDL_JOYSTICK_DISABLE_UDEV");
+            enumeration_method = ENUMERATION_FALLBACK;
+
+        } else if (access("/.flatpak-info", F_OK) == 0
+                 || access("/run/host/container-manager", F_OK) == 0) {
+            /* Explicitly check `/.flatpak-info` because, for old versions of
+             * Flatpak, this was the only available way to tell if we were in
+             * a Flatpak container. */
+            SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
+                         "Container detected, disabling udev integration");
+            enumeration_method = ENUMERATION_FALLBACK;
+
+        } else {
+            SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
+                         "Using udev for joystick device discovery");
+            enumeration_method = ENUMERATION_LIBUDEV;
+        }
+    }
+
     if (enumeration_method == ENUMERATION_LIBUDEV) {
         if (SDL_UDEV_Init() < 0) {
             return SDL_SetError("Could not initialize UDEV");
@@ -1573,9 +1624,13 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
     SDL_Joystick *joystick;
     SDL_joylist_item *item = JoystickByDevIndex(device_index);
 
-    if (item->mapping) {
-        SDL_memcpy(out, item->mapping, sizeof(*out));
-        return SDL_TRUE;
+    if (item->checked_mapping) {
+        if (item->mapping) {
+            SDL_memcpy(out, item->mapping, sizeof(*out));
+            return SDL_TRUE;
+        } else {
+            return SDL_FALSE;
+        }
     }
 
     /* We temporarily open the device to check how it's configured. Make
@@ -1595,6 +1650,8 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
         return SDL_FALSE;
     }
 
+    item->checked_mapping = SDL_TRUE;
+
     if (PrepareJoystickHwdata(joystick, item) == -1) {
         SDL_free(joystick->hwdata);
         SDL_free(joystick);

+ 14 - 10
Engine/lib/sdl/src/joystick/windows/SDL_rawinputjoystick.c

@@ -62,6 +62,7 @@ typedef struct WindowsGamingInputGamepadState WindowsGamingInputGamepadState;
 #define GamepadButtons_GUIDE 0x40000000
 #define COBJMACROS
 #include "windows.gaming.input.h"
+#include <roapi.h>
 #endif
 
 #if defined(SDL_JOYSTICK_RAWINPUT_XINPUT) || defined(SDL_JOYSTICK_RAWINPUT_WGI)
@@ -565,22 +566,24 @@ RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
     if (!wgi_state.initialized) {
         static const IID SDL_IID_IGamepadStatics = { 0x8BBCE529, 0xD49C, 0x39E9, { 0x95, 0x60, 0xE4, 0x7D, 0xDE, 0x96, 0xB7, 0xC8 } };
         HRESULT hr;
-        HMODULE hModule;
 
-        /* I think this takes care of RoInitialize() in a way that is compatible with the rest of SDL */
-        if (FAILED(WIN_CoInitialize())) {
+        if (FAILED(WIN_RoInitialize())) {
             return;
         }
         wgi_state.initialized = SDL_TRUE;
         wgi_state.dirty = SDL_TRUE;
 
-        hModule = LoadLibraryA("combase.dll");
-        if (hModule != NULL) {
+        {
             typedef HRESULT (WINAPI *WindowsCreateStringReference_t)(PCWSTR sourceString, UINT32 length, HSTRING_HEADER *hstringHeader, HSTRING* string);
             typedef HRESULT (WINAPI *RoGetActivationFactory_t)(HSTRING activatableClassId, REFIID iid, void** factory);
 
-            WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)GetProcAddress(hModule, "WindowsCreateStringReference");
-            RoGetActivationFactory_t RoGetActivationFactoryFunc = (RoGetActivationFactory_t)GetProcAddress(hModule, "RoGetActivationFactory");
+#ifdef __WINRT__
+            WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = WindowsCreateStringReference;
+            RoGetActivationFactory_t RoGetActivationFactoryFunc = RoGetActivationFactory;
+#else
+            WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)WIN_LoadComBaseFunction("WindowsCreateStringReference");
+            RoGetActivationFactory_t RoGetActivationFactoryFunc = (RoGetActivationFactory_t)WIN_LoadComBaseFunction("RoGetActivationFactory");
+#endif
             if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) {
                 PCWSTR pNamespace = L"Windows.Gaming.Input.Gamepad";
                 HSTRING_HEADER hNamespaceStringHeader;
@@ -591,7 +594,6 @@ RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
                     RoGetActivationFactoryFunc(hNamespaceString, &SDL_IID_IGamepadStatics, (void **)&wgi_state.gamepad_statics);
                 }
             }
-            FreeLibrary(hModule);
         }
     }
 }
@@ -657,7 +659,7 @@ RAWINPUT_QuitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
             __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_Release(wgi_state.gamepad_statics);
             wgi_state.gamepad_statics = NULL;
         }
-        WIN_CoUninitialize();
+        WIN_RoUninitialize();
         wgi_state.initialized = SDL_FALSE;
     }
 }
@@ -1320,8 +1322,10 @@ RAWINPUT_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint
         if (!SUCCEEDED(hr)) {
             return SDL_SetError("Setting vibration failed: 0x%lx\n", hr);
         }
+        return 0;
+    } else {
+        return SDL_SetError("Controller isn't correlated yet, try hitting a button first");
     }
-    return 0;
 #else
     return SDL_Unsupported();
 #endif

+ 38 - 25
Engine/lib/sdl/src/joystick/windows/SDL_windows_gaming_input.c

@@ -68,6 +68,7 @@ static struct {
     EventRegistrationToken controller_added_token;
     EventRegistrationToken controller_removed_token;
     int controller_count;
+    SDL_bool ro_initialized;
     WindowsGamingInputControllerState *controllers;
 } wgi;
 
@@ -260,10 +261,9 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
             WindowsGetStringRawBufferFunc = WindowsGetStringRawBuffer;
             WindowsDeleteStringFunc = WindowsDeleteString;
 #else
-            HMODULE hModule = LoadLibraryA("combase.dll");
-            if (hModule != NULL) {
-                WindowsGetStringRawBufferFunc = (WindowsGetStringRawBuffer_t)GetProcAddress(hModule, "WindowsGetStringRawBuffer");
-                WindowsDeleteStringFunc = (WindowsDeleteString_t)GetProcAddress(hModule, "WindowsDeleteString");
+            {
+                WindowsGetStringRawBufferFunc = (WindowsGetStringRawBuffer_t)WIN_LoadComBaseFunction("WindowsGetStringRawBuffer");
+                WindowsDeleteStringFunc = (WindowsDeleteString_t)WIN_LoadComBaseFunction("WindowsDeleteString");
             }
 #endif /* __WINRT__ */
             if (WindowsGetStringRawBufferFunc && WindowsDeleteStringFunc) {
@@ -277,11 +277,6 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
                     WindowsDeleteStringFunc(hString);
                 }
             }
-#ifndef __WINRT__
-            if (hModule != NULL) {
-                FreeLibrary(hModule);
-            }
-#endif
             __x_ABI_CWindows_CGaming_CInput_CIRawGameController2_Release(controller2);
         }
         if (!name) {
@@ -444,23 +439,43 @@ WGI_JoystickInit(void)
 
     WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = NULL;
     RoGetActivationFactory_t RoGetActivationFactoryFunc = NULL;
-#ifndef __WINRT__
-    HMODULE hModule;
-#endif
     HRESULT hr;
 
-    if (FAILED(WIN_CoInitialize())) {
-        return SDL_SetError("CoInitialize() failed");
+    if (FAILED(WIN_RoInitialize())) {
+        return SDL_SetError("RoInitialize() failed");
+    }
+    wgi.ro_initialized = SDL_TRUE;
+
+#ifndef __WINRT__
+    {
+        /* There seems to be a bug in Windows where a dependency of WGI can be unloaded from memory prior to WGI itself.
+         * This results in Windows_Gaming_Input!GameController::~GameController() invoking an unloaded DLL and crashing.
+         * As a workaround, we will keep a reference to the MTA to prevent COM from unloading DLLs later.
+         * See https://github.com/libsdl-org/SDL/issues/5552 for more details.
+         */
+        static PVOID cookie = NULL;
+        if (!cookie) {
+            typedef HRESULT (WINAPI *CoIncrementMTAUsage_t)(PVOID* pCookie);
+            CoIncrementMTAUsage_t CoIncrementMTAUsageFunc = (CoIncrementMTAUsage_t)WIN_LoadComBaseFunction("CoIncrementMTAUsage");
+            if (CoIncrementMTAUsageFunc) {
+                if (FAILED(CoIncrementMTAUsageFunc(&cookie))) {
+                    return SDL_SetError("CoIncrementMTAUsage() failed");
+                }
+            } else {
+                /* CoIncrementMTAUsage() is present since Win8, so we should never make it here. */
+                return SDL_SetError("CoIncrementMTAUsage() not found");
+            }
+        }
     }
+#endif
 
 #ifdef __WINRT__
     WindowsCreateStringReferenceFunc = WindowsCreateStringReference;
     RoGetActivationFactoryFunc = RoGetActivationFactory;
 #else
-    hModule = LoadLibraryA("combase.dll");
-    if (hModule != NULL) {
-        WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)GetProcAddress(hModule, "WindowsCreateStringReference");
-        RoGetActivationFactoryFunc = (RoGetActivationFactory_t)GetProcAddress(hModule, "RoGetActivationFactory");
+    {
+        WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)WIN_LoadComBaseFunction("WindowsCreateStringReference");
+        RoGetActivationFactoryFunc = (RoGetActivationFactory_t)WIN_LoadComBaseFunction("RoGetActivationFactory");
     }
 #endif /* __WINRT__ */
     if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) {
@@ -519,11 +534,6 @@ WGI_JoystickInit(void)
             }
         }
     }
-#ifndef __WINRT__
-    if (hModule != NULL) {
-        FreeLibrary(hModule);
-    }
-#endif
 
     if (wgi.statics) {
         __FIVectorView_1_Windows__CGaming__CInput__CRawGameController *controllers;
@@ -863,9 +873,12 @@ WGI_JoystickQuit(void)
         __x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_remove_RawGameControllerRemoved(wgi.statics, wgi.controller_removed_token);
         __x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_Release(wgi.statics);
     }
-    SDL_zero(wgi);
 
-    WIN_CoUninitialize();
+    if (wgi.ro_initialized) {
+        WIN_RoUninitialize();
+    }
+
+    SDL_zero(wgi);
 }
 
 static SDL_bool

+ 71 - 0
Engine/lib/sdl/src/locale/vita/SDL_syslocale.c

@@ -0,0 +1,71 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2022 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, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+#include "../SDL_syslocale.h"
+
+#include <psp2/apputil.h>
+#include <psp2/system_param.h>
+
+void
+SDL_SYS_GetPreferredLocales(char *buf, size_t buflen)
+{
+    const char *vita_locales[] = {
+        "ja_JP",
+        "en_US",
+        "fr_FR",
+        "es_ES",
+        "de_DE",
+        "it_IT",
+        "nl_NL",
+        "pt_PT",
+        "ru_RU",
+        "ko_KR",
+        "zh_TW",
+        "zh_CN",
+        "fi_FI",
+        "sv_SE",
+        "da_DK",
+        "no_NO",
+        "pl_PL",
+        "pt_BR",
+        "en_GB",
+        "tr_TR",
+    };
+
+    Sint32 language = SCE_SYSTEM_PARAM_LANG_ENGLISH_US;
+    SceAppUtilInitParam initParam;
+    SceAppUtilBootParam bootParam;
+    SDL_zero(initParam);
+    SDL_zero(bootParam);
+    sceAppUtilInit(&initParam, &bootParam);
+    sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_LANG, &language);
+
+    if (language < 0 || language > SCE_SYSTEM_PARAM_LANG_TURKISH)
+        language = SCE_SYSTEM_PARAM_LANG_ENGLISH_US; // default to english
+
+    SDL_strlcpy(buf, vita_locales[language], buflen);
+
+    sceAppUtilShutdown();
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
+

+ 4 - 4
Engine/lib/sdl/src/main/windows/version.rc

@@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,0,21,0
- PRODUCTVERSION 2,0,21,0
+ FILEVERSION 2,0,22,0
+ PRODUCTVERSION 2,0,22,0
  FILEFLAGSMASK 0x3fL
  FILEFLAGS 0x0L
  FILEOS 0x40004L
@@ -23,12 +23,12 @@ BEGIN
         BEGIN
             VALUE "CompanyName", "\0"
             VALUE "FileDescription", "SDL\0"
-            VALUE "FileVersion", "2, 0, 21, 0\0"
+            VALUE "FileVersion", "2, 0, 22, 0\0"
             VALUE "InternalName", "SDL\0"
             VALUE "LegalCopyright", "Copyright (C) 2022 Sam Lantinga\0"
             VALUE "OriginalFilename", "SDL2.dll\0"
             VALUE "ProductName", "Simple DirectMedia Layer\0"
-            VALUE "ProductVersion", "2, 0, 21, 0\0"
+            VALUE "ProductVersion", "2, 0, 22, 0\0"
         END
     END
     BLOCK "VarFileInfo"

+ 60 - 39
Engine/lib/sdl/src/render/SDL_render.c

@@ -356,7 +356,7 @@ QueueCmdSetViewport(SDL_Renderer *renderer)
         if (cmd != NULL) {
             cmd->command = SDL_RENDERCMD_SETVIEWPORT;
             cmd->data.viewport.first = 0;  /* render backend will fill this in. */
-            /* Convert SDL_FRect to SDL_Rect */
+            /* Convert SDL_DRect to SDL_Rect */
             cmd->data.viewport.rect.x = (int)SDL_floor(renderer->viewport.x);
             cmd->data.viewport.rect.y = (int)SDL_floor(renderer->viewport.y);
             cmd->data.viewport.rect.w = (int)SDL_floor(renderer->viewport.w);
@@ -386,7 +386,7 @@ QueueCmdSetClipRect(SDL_Renderer *renderer)
         } else {
             cmd->command = SDL_RENDERCMD_SETCLIPRECT;
             cmd->data.cliprect.enabled = renderer->clipping_enabled;
-            /* Convert SDL_FRect to SDL_Rect */
+            /* Convert SDL_DRect to SDL_Rect */
             cmd->data.cliprect.rect.x = (int)SDL_floor(renderer->clip_rect.x);
             cmd->data.cliprect.rect.y = (int)SDL_floor(renderer->clip_rect.y);
             cmd->data.cliprect.rect.w = (int)SDL_floor(renderer->clip_rect.w);
@@ -580,10 +580,10 @@ QueueCmdFillRects(SDL_Renderer *renderer, const SDL_FRect * rects, const int cou
                 if (retval < 0) {
                     cmd->command = SDL_RENDERCMD_NO_OP;
                 }
-
-                SDL_small_free(xy, isstack1);
-                SDL_small_free(indices, isstack2);
             }
+            SDL_small_free(xy, isstack1);
+            SDL_small_free(indices, isstack2);
+            
         } else {
             retval = renderer->QueueFillRects(renderer, cmd, rects, count);
             if (retval < 0) {
@@ -676,7 +676,7 @@ SDL_GetRenderDriverInfo(int index, SDL_RendererInfo * info)
 #endif
 }
 
-static void GetWindowViewportValues(SDL_Renderer *renderer, int *logical_w, int *logical_h, SDL_FRect *viewport, SDL_FPoint *scale)
+static void GetWindowViewportValues(SDL_Renderer *renderer, int *logical_w, int *logical_h, SDL_DRect *viewport, SDL_FPoint *scale)
 {
     SDL_LockMutex(renderer->target_mutex);
     *logical_w = renderer->target ? renderer->logical_w_backup : renderer->logical_w;
@@ -698,7 +698,17 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
                 renderer->WindowEvent(renderer, &event->window);
             }
 
-            if (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
+            /* In addition to size changes, we also want to do this block for
+             * moves as well, for two reasons:
+             *
+             * 1. The window could be moved to a new display, which has a new
+             *    DPI and therefore a new window/drawable ratio
+             * 2. For whatever reason, the viewport can get messed up during
+             *    window movement (this has been observed on macOS), so this is
+             *    also a good opportunity to force viewport updates
+             */
+            if (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED ||
+                event->window.event == SDL_WINDOWEVENT_MOVED) {
                 /* Make sure we're operating on the default render target */
                 SDL_Texture *saved_target = SDL_GetRenderTarget(renderer);
                 if (saved_target) {
@@ -728,10 +738,10 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
                         SDL_GetWindowSize(renderer->window, &w, &h);
                     }
 
-                    renderer->viewport.x = 0;
-                    renderer->viewport.y = 0;
-                    renderer->viewport.w = (float) w;
-                    renderer->viewport.h = (float) h;
+                    renderer->viewport.x = (double)0;
+                    renderer->viewport.y = (double)0;
+                    renderer->viewport.w = (double)w;
+                    renderer->viewport.h = (double)h;
                     QueueCmdSetViewport(renderer);
                     FlushRenderCommandsIfNotBatching(renderer);
                 }
@@ -758,7 +768,7 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
         SDL_Window *window = SDL_GetWindowFromID(event->motion.windowID);
         if (window == renderer->window) {
             int logical_w, logical_h;
-            SDL_FRect viewport;
+            SDL_DRect viewport;
             SDL_FPoint scale;
             GetWindowViewportValues(renderer, &logical_w, &logical_h, &viewport, &scale);
             if (logical_w) {
@@ -785,7 +795,7 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
         SDL_Window *window = SDL_GetWindowFromID(event->button.windowID);
         if (window == renderer->window) {
             int logical_w, logical_h;
-            SDL_FRect viewport;
+            SDL_DRect viewport;
             SDL_FPoint scale;
             GetWindowViewportValues(renderer, &logical_w, &logical_h, &viewport, &scale);
             if (logical_w) {
@@ -800,7 +810,7 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
                event->type == SDL_FINGERMOTION) {
         int logical_w, logical_h;
         float physical_w, physical_h;
-        SDL_FRect viewport;
+        SDL_DRect viewport;
         SDL_FPoint scale;
         GetWindowViewportValues(renderer, &logical_w, &logical_h, &viewport, &scale);
 
@@ -1095,6 +1105,13 @@ SDL_GetRenderer(SDL_Window * window)
     return (SDL_Renderer *)SDL_GetWindowData(window, SDL_WINDOWRENDERDATA);
 }
 
+SDL_Window *
+SDL_RenderGetWindow(SDL_Renderer *renderer)
+{
+    CHECK_RENDERER_MAGIC(renderer, NULL);
+    return renderer->window;
+}
+
 int
 SDL_GetRendererInfo(SDL_Renderer * renderer, SDL_RendererInfo * info)
 {
@@ -1585,10 +1602,11 @@ SDL_SetTextureScaleMode(SDL_Texture * texture, SDL_ScaleMode scaleMode)
     CHECK_TEXTURE_MAGIC(texture, -1);
 
     renderer = texture->renderer;
-    renderer->SetTextureScaleMode(renderer, texture, scaleMode);
     texture->scaleMode = scaleMode;
     if (texture->native) {
         return SDL_SetTextureScaleMode(texture->native, scaleMode);
+    } else {
+        renderer->SetTextureScaleMode(renderer, texture, scaleMode);
     }
     return 0;
 }
@@ -2210,10 +2228,10 @@ SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
     }
 
     if (texture) {
-        renderer->viewport.x = 0.0f;
-        renderer->viewport.y = 0.0f;
-        renderer->viewport.w = (float) texture->w;
-        renderer->viewport.h = (float) texture->h;
+        renderer->viewport.x = (double)0;
+        renderer->viewport.y = (double)0;
+        renderer->viewport.w = (double)texture->w;
+        renderer->viewport.h = (double)texture->h;
         SDL_zero(renderer->clip_rect);
         renderer->clipping_enabled = SDL_FALSE;
         renderer->scale.x = 1.0f;
@@ -2245,6 +2263,8 @@ SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
 SDL_Texture *
 SDL_GetRenderTarget(SDL_Renderer *renderer)
 {
+    CHECK_RENDERER_MAGIC(renderer, NULL);
+
     return renderer->target;
 }
 
@@ -2420,19 +2440,19 @@ SDL_RenderSetViewport(SDL_Renderer * renderer, const SDL_Rect * rect)
     CHECK_RENDERER_MAGIC(renderer, -1);
 
     if (rect) {
-        renderer->viewport.x = rect->x * renderer->scale.x;
-        renderer->viewport.y = rect->y * renderer->scale.y;
-        renderer->viewport.w = rect->w * renderer->scale.x;
-        renderer->viewport.h = rect->h * renderer->scale.y;
+        renderer->viewport.x = (double)rect->x * renderer->scale.x;
+        renderer->viewport.y = (double)rect->y * renderer->scale.y;
+        renderer->viewport.w = (double)rect->w * renderer->scale.x;
+        renderer->viewport.h = (double)rect->h * renderer->scale.y;
     } else {
         int w, h;
         if (SDL_GetRendererOutputSize(renderer, &w, &h) < 0) {
             return -1;
         }
-        renderer->viewport.x = 0.0f;
-        renderer->viewport.y = 0.0f;
-        renderer->viewport.w = (float) w;
-        renderer->viewport.h = (float) h;
+        renderer->viewport.x = (double)0;
+        renderer->viewport.y = (double)0;
+        renderer->viewport.w = (double)w;
+        renderer->viewport.h = (double)h;
     }
     retval = QueueCmdSetViewport(renderer);
     return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer);
@@ -2456,8 +2476,8 @@ RenderGetViewportSize(SDL_Renderer * renderer, SDL_FRect * rect)
 {
     rect->x = 0.0f;
     rect->y = 0.0f;
-    rect->w = renderer->viewport.w / renderer->scale.x;
-    rect->h = renderer->viewport.h / renderer->scale.y;
+    rect->w = (float)(renderer->viewport.w / renderer->scale.x);
+    rect->h = (float)(renderer->viewport.h / renderer->scale.y);
 }
 
 int
@@ -2468,10 +2488,10 @@ SDL_RenderSetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect)
 
     if (rect) {
         renderer->clipping_enabled = SDL_TRUE;
-        renderer->clip_rect.x = rect->x * renderer->scale.x;
-        renderer->clip_rect.y = rect->y * renderer->scale.y;
-        renderer->clip_rect.w = rect->w * renderer->scale.x;
-        renderer->clip_rect.h = rect->h * renderer->scale.y;
+        renderer->clip_rect.x = (double)rect->x * renderer->scale.x;
+        renderer->clip_rect.y = (double)rect->y * renderer->scale.y;
+        renderer->clip_rect.w = (double)rect->w * renderer->scale.x;
+        renderer->clip_rect.h = (double)rect->h * renderer->scale.y;
     } else {
         renderer->clipping_enabled = SDL_FALSE;
         SDL_zero(renderer->clip_rect);
@@ -2535,10 +2555,10 @@ SDL_RenderWindowToLogical(SDL_Renderer * renderer, int windowX, int windowY, flo
     window_physical_y = ((float) windowY) / renderer->dpi_scale.y;
 
     if (logicalX) {
-        *logicalX = (window_physical_x - renderer->viewport.x) / renderer->scale.x;
+        *logicalX = (float)((window_physical_x - renderer->viewport.x) / renderer->scale.x);
     }
     if (logicalY) {
-        *logicalY = (window_physical_y - renderer->viewport.y) / renderer->scale.y;
+        *logicalY = (float)((window_physical_y - renderer->viewport.y) / renderer->scale.y);
     }
 }
 
@@ -2549,8 +2569,8 @@ SDL_RenderLogicalToWindow(SDL_Renderer * renderer, float logicalX, float logical
 
     CHECK_RENDERER_MAGIC(renderer, );
 
-    window_physical_x = (logicalX * renderer->scale.x) + renderer->viewport.x;
-    window_physical_y = (logicalY * renderer->scale.y) + renderer->viewport.y;
+    window_physical_x = (float)((logicalX * renderer->scale.x) + renderer->viewport.x);
+    window_physical_y = (float)((logicalY * renderer->scale.y) + renderer->viewport.y);
 
     if (windowX) {
         *windowX = (int)(window_physical_x * renderer->dpi_scale.x);
@@ -3138,10 +3158,11 @@ SDL_RenderDrawLinesF(SDL_Renderer * renderer,
                     num_vertices, indices, num_indices, size_indices,
                     1.0f, 1.0f);
 
-            SDL_small_free(xy, isstack1);
-            SDL_small_free(indices, isstack2);
         }
 
+        SDL_small_free(xy, isstack1);
+        SDL_small_free(indices, isstack2);
+
     } else if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) {
         retval = RenderDrawLinesWithRectsF(renderer, points, count);
     } else {

+ 19 - 6
Engine/lib/sdl/src/render/SDL_sysrender.h

@@ -28,6 +28,19 @@
 #include "SDL_mutex.h"
 #include "SDL_yuv_sw_c.h"
 
+
+/**
+ * A rectangle, with the origin at the upper left (double precision).
+ */
+typedef struct SDL_DRect
+{
+    double x;
+    double y;
+    double w;
+    double h;
+} SDL_DRect;
+
+
 /* The SDL 2D rendering system */
 
 typedef struct SDL_RenderDriver SDL_RenderDriver;
@@ -201,12 +214,12 @@ struct SDL_Renderer
     SDL_bool integer_scale;
 
     /* The drawable area within the window */
-    SDL_FRect viewport;
-    SDL_FRect viewport_backup;
+    SDL_DRect viewport;
+    SDL_DRect viewport_backup;
 
     /* The clip rectangle within the window */
-    SDL_FRect clip_rect;
-    SDL_FRect clip_rect_backup;
+    SDL_DRect clip_rect;
+    SDL_DRect clip_rect_backup;
 
     /* Wether or not the clipping rectangle is used. */
     SDL_bool clipping_enabled;
@@ -244,8 +257,8 @@ struct SDL_Renderer
     SDL_RenderCommand *render_commands_pool;
     Uint32 render_command_generation;
     Uint32 last_queued_color;
-    SDL_FRect last_queued_viewport;
-    SDL_FRect last_queued_cliprect;
+    SDL_DRect last_queued_viewport;
+    SDL_DRect last_queued_cliprect;
     SDL_bool last_queued_cliprect_enabled;
     SDL_bool color_queued;
     SDL_bool viewport_queued;

+ 35 - 9
Engine/lib/sdl/src/render/direct3d/SDL_render_d3d.c

@@ -347,7 +347,8 @@ D3D_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
     }
 }
 
-static D3DBLEND GetBlendFunc(SDL_BlendFactor factor)
+static D3DBLEND
+GetBlendFunc(SDL_BlendFactor factor)
 {
     switch (factor) {
     case SDL_BLENDFACTOR_ZERO:
@@ -370,9 +371,28 @@ static D3DBLEND GetBlendFunc(SDL_BlendFactor factor)
         return D3DBLEND_DESTALPHA;
     case SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA:
         return D3DBLEND_INVDESTALPHA;
-    default:
-        return (D3DBLEND)0;
+    default: break;
     }
+    return (D3DBLEND) 0;
+}
+
+static D3DBLENDOP
+GetBlendEquation(SDL_BlendOperation operation)
+{
+    switch (operation) {
+    case SDL_BLENDOPERATION_ADD:
+        return D3DBLENDOP_ADD;
+    case SDL_BLENDOPERATION_SUBTRACT:
+        return D3DBLENDOP_SUBTRACT;
+    case SDL_BLENDOPERATION_REV_SUBTRACT:
+        return D3DBLENDOP_REVSUBTRACT;
+    case SDL_BLENDOPERATION_MINIMUM:
+        return D3DBLENDOP_MIN;
+    case SDL_BLENDOPERATION_MAXIMUM:
+        return D3DBLENDOP_MAX;
+    default: break;
+    }
+    return (D3DBLENDOP) 0;
 }
 
 static SDL_bool
@@ -387,14 +407,16 @@ D3D_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
     SDL_BlendOperation alphaOperation = SDL_GetBlendModeAlphaOperation(blendMode);
 
     if (!GetBlendFunc(srcColorFactor) || !GetBlendFunc(srcAlphaFactor) ||
-        !GetBlendFunc(dstColorFactor) || !GetBlendFunc(dstAlphaFactor)) {
+        !GetBlendEquation(colorOperation) ||
+        !GetBlendFunc(dstColorFactor) || !GetBlendFunc(dstAlphaFactor) ||
+        !GetBlendEquation(alphaOperation)) {
         return SDL_FALSE;
     }
-    if ((srcColorFactor != srcAlphaFactor || dstColorFactor != dstAlphaFactor) && !data->enableSeparateAlphaBlend) {
-        return SDL_FALSE;
-    }
-    if (colorOperation != SDL_BLENDOPERATION_ADD || alphaOperation != SDL_BLENDOPERATION_ADD) {
-        return SDL_FALSE;
+
+    if (!data->enableSeparateAlphaBlend) {
+        if ((srcColorFactor != srcAlphaFactor) || (dstColorFactor != dstAlphaFactor) || (colorOperation != alphaOperation)) {
+            return SDL_FALSE;
+        }
     }
     return SDL_TRUE;
 }
@@ -1040,11 +1062,15 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd)
                                             GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blend)));
             IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
                                             GetBlendFunc(SDL_GetBlendModeDstColorFactor(blend)));
+            IDirect3DDevice9_SetRenderState(data->device, D3DRS_BLENDOP,
+                                            GetBlendEquation(SDL_GetBlendModeColorOperation(blend)));
             if (data->enableSeparateAlphaBlend) {
                 IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLENDALPHA,
                                                 GetBlendFunc(SDL_GetBlendModeSrcAlphaFactor(blend)));
                 IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLENDALPHA,
                                                 GetBlendFunc(SDL_GetBlendModeDstAlphaFactor(blend)));
+                IDirect3DDevice9_SetRenderState(data->device, D3DRS_BLENDOPALPHA,
+                                                GetBlendEquation(SDL_GetBlendModeAlphaOperation(blend)));
             }
         }
 

+ 10 - 0
Engine/lib/sdl/src/render/direct3d11/SDL_render_d3d11.c

@@ -998,6 +998,16 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
         goto done;
     }
 
+    /* Set the swap chain target immediately, so that a target is always set
+     * even before we get to SetDrawState. Without this it's possible to hit
+     * null references in places like ReadPixels!
+     */
+    ID3D11DeviceContext_OMSetRenderTargets(data->d3dContext,
+        1,
+        &data->mainRenderTargetView,
+        NULL
+        );
+
     data->viewportDirty = SDL_TRUE;
 
 done:

+ 25 - 3
Engine/lib/sdl/src/render/opengl/SDL_render_gl.c

@@ -30,6 +30,11 @@
 #include <OpenGL/OpenGL.h>
 #endif
 
+#ifdef SDL_VIDEO_VITA_PVR_OGL
+#include <GL/gl.h>
+#include <GL/glext.h>
+#endif
+
 /* To prevent unnecessary window recreation, 
  * these should match the defaults selected in SDL_GL_ResetAttributes 
  */
@@ -319,6 +324,20 @@ GL_GetFBO(GL_RenderData *data, Uint32 w, Uint32 h)
     return result;
 }
 
+static void
+GL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
+{
+    /* If the window x/y/w/h changed at all, assume the viewport has been
+     * changed behind our backs. x/y changes might seem weird but viewport
+     * resets have been observed on macOS at minimum!
+     */
+    if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED ||
+        event->event == SDL_WINDOWEVENT_MOVED) {
+        GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+        data->drawstate.viewport_dirty = SDL_TRUE;
+    }
+}
+
 static int
 GL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
 {
@@ -1212,9 +1231,9 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
     }
 
 #ifdef __MACOSX__
-    // On macOS, moving the window seems to invalidate the OpenGL viewport state,
-    // so don't bother trying to persist it across frames; always reset it.
-    // Workaround for: https://github.com/libsdl-org/SDL/issues/1504
+    // On macOS on older systems, the OpenGL view change and resize events aren't
+    // necessarily synchronized, so just always reset it.
+    // Workaround for: https://discourse.libsdl.org/t/sdl-2-0-22-prerelease/35306/6
     data->drawstate.viewport_dirty = SDL_TRUE;
 #endif
 
@@ -1733,6 +1752,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
     SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major);
     SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minor);
 
+#ifndef SDL_VIDEO_VITA_PVR_OGL
     window_flags = SDL_GetWindowFlags(window);
     if (!(window_flags & SDL_WINDOW_OPENGL) ||
         profile_mask == SDL_GL_CONTEXT_PROFILE_ES || major != RENDERER_CONTEXT_MAJOR || minor != RENDERER_CONTEXT_MINOR) {
@@ -1746,6 +1766,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
             goto error;
         }
     }
+#endif
 
     renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
     if (!renderer) {
@@ -1760,6 +1781,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
         goto error;
     }
 
+    renderer->WindowEvent = GL_WindowEvent;
     renderer->GetOutputSize = GL_GetOutputSize;
     renderer->SupportsBlendMode = GL_SupportsBlendMode;
     renderer->CreateTexture = GL_CreateTexture;

+ 260 - 27
Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm.c

@@ -61,6 +61,11 @@ static int VITA_GXM_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * text
     const Uint8 *Uplane, int Upitch,
     const Uint8 *Vplane, int Vpitch);
 
+static int VITA_GXM_UpdateTextureNV(SDL_Renderer * renderer, SDL_Texture * texture,
+    const SDL_Rect * rect,
+    const Uint8 *Yplane, int Ypitch,
+    const Uint8 *UVplane, int UVpitch);
+
 static int VITA_GXM_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
     const SDL_Rect *rect, void **pixels, int *pitch);
 
@@ -105,12 +110,16 @@ SDL_RenderDriver VITA_GXM_RenderDriver = {
     .info = {
         .name = "VITA gxm",
         .flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE,
-        .num_texture_formats = 4,
+        .num_texture_formats = 8,
         .texture_formats = {
             [0] = SDL_PIXELFORMAT_ABGR8888,
             [1] = SDL_PIXELFORMAT_ARGB8888,
             [2] = SDL_PIXELFORMAT_RGB565,
-            [3] = SDL_PIXELFORMAT_BGR565
+            [3] = SDL_PIXELFORMAT_BGR565,
+            [4] = SDL_PIXELFORMAT_YV12,
+            [5] = SDL_PIXELFORMAT_IYUV,
+            [6] = SDL_PIXELFORMAT_NV12,
+            [7] = SDL_PIXELFORMAT_NV21,
         },
         .max_texture_width = 4096,
         .max_texture_height = 4096,
@@ -133,6 +142,15 @@ PixelFormatToVITAFMT(Uint32 format)
         return SCE_GXM_TEXTURE_FORMAT_U5U6U5_RGB;
     case SDL_PIXELFORMAT_BGR565:
         return SCE_GXM_TEXTURE_FORMAT_U5U6U5_BGR;
+    case SDL_PIXELFORMAT_YV12:
+        return SCE_GXM_TEXTURE_FORMAT_YVU420P3_CSC0;
+    case SDL_PIXELFORMAT_IYUV:
+        return SCE_GXM_TEXTURE_FORMAT_YUV420P3_CSC0;
+    // should be the other way around. looks like SCE bug.
+    case SDL_PIXELFORMAT_NV12:
+        return SCE_GXM_TEXTURE_FORMAT_YVU420P2_CSC0;
+    case SDL_PIXELFORMAT_NV21:
+        return SCE_GXM_TEXTURE_FORMAT_YUV420P2_CSC0;
     default:
         return SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR;
     }
@@ -228,6 +246,7 @@ VITA_GXM_CreateRenderer(SDL_Window *window, Uint32 flags)
     renderer->UpdateTexture = VITA_GXM_UpdateTexture;
 #if SDL_HAVE_YUV
     renderer->UpdateTextureYUV = VITA_GXM_UpdateTextureYUV;
+    renderer->UpdateTextureNV = VITA_GXM_UpdateTextureNV;
 #endif
     renderer->LockTexture = VITA_GXM_LockTexture;
     renderer->UnlockTexture = VITA_GXM_UnlockTexture;
@@ -295,7 +314,17 @@ VITA_GXM_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
         return SDL_OutOfMemory();
     }
 
-    vita_texture->tex = create_gxm_texture(data, texture->w, texture->h, PixelFormatToVITAFMT(texture->format), (texture->access == SDL_TEXTUREACCESS_TARGET));
+    vita_texture->tex = create_gxm_texture(
+        data,
+        texture->w,
+        texture->h,
+        PixelFormatToVITAFMT(texture->format),
+        (texture->access == SDL_TEXTUREACCESS_TARGET),
+        &(vita_texture->w),
+        &(vita_texture->h),
+        &(vita_texture->pitch),
+        &(vita_texture->wscale)
+    );
 
     if (!vita_texture->tex) {
         SDL_free(vita_texture);
@@ -306,38 +335,129 @@ VITA_GXM_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
 
     VITA_GXM_SetTextureScaleMode(renderer, texture, texture->scaleMode);
 
-    vita_texture->w = gxm_texture_get_width(vita_texture->tex);
-    vita_texture->h = gxm_texture_get_height(vita_texture->tex);
-    vita_texture->pitch = gxm_texture_get_stride(vita_texture->tex);
+#if SDL_HAVE_YUV
+    vita_texture->yuv = ((texture->format == SDL_PIXELFORMAT_IYUV) || (texture->format == SDL_PIXELFORMAT_YV12));
+    vita_texture->nv12 = ((texture->format == SDL_PIXELFORMAT_NV12) || (texture->format == SDL_PIXELFORMAT_NV21));
+#endif
 
     return 0;
 }
 
+static void VITA_GXM_SetYUVProfile(SDL_Renderer * renderer, SDL_Texture *texture)
+{
+    VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
+    int ret = 0;
+    switch (SDL_GetYUVConversionModeForResolution(texture->w, texture->h)) {
+    case SDL_YUV_CONVERSION_BT601:
+        ret = sceGxmSetYuvProfile(data->gxm_context, 0, SCE_GXM_YUV_PROFILE_BT601_STANDARD);
+        break;
+    case SDL_YUV_CONVERSION_BT709:
+        ret = sceGxmSetYuvProfile(data->gxm_context, 0, SCE_GXM_YUV_PROFILE_BT709_STANDARD);
+        break;
+    case SDL_YUV_CONVERSION_JPEG:
+    default:
+        SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Unsupported YUV profile: %d\n", SDL_GetYUVConversionModeForResolution(texture->w, texture->h));
+        break;
+  }
+
+  if (ret < 0) {
+      SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Setting YUV profile failed: %x\n", ret);
+  }
+}
 
 static int
 VITA_GXM_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture,
     const SDL_Rect *rect, const void *pixels, int pitch)
 {
-    const Uint8 *src;
+    VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) texture->driverdata;
     Uint8 *dst;
-    int row, length,dpitch;
-    src = pixels;
+    int row, length, dpitch;
+
+#if SDL_HAVE_YUV
+    if (vita_texture->yuv || vita_texture->nv12) {
+        VITA_GXM_SetYUVProfile(renderer, texture);
+    }
+#endif
 
     VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch);
     length = rect->w * SDL_BYTESPERPIXEL(texture->format);
     if (length == pitch && length == dpitch) {
-        SDL_memcpy(dst, src, length*rect->h);
+        SDL_memcpy(dst, pixels, length*rect->h);
     } else {
         for (row = 0; row < rect->h; ++row) {
-            SDL_memcpy(dst, src, length);
-            src += pitch;
+            SDL_memcpy(dst, pixels, length);
+            pixels += pitch;
             dst += dpitch;
         }
     }
 
+#if SDL_HAVE_YUV
+    if (vita_texture->yuv) {
+        void *Udst;
+        void *Vdst;
+        int uv_pitch = (dpitch+1) / 2;
+        int uv_src_pitch = (pitch+1) / 2;
+        SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2};
+
+        // skip Y plane
+        Uint8 *Dpixels = gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h);
+
+        Udst = Dpixels + (UVrect.y * uv_pitch) + UVrect.x;
+        Vdst = Dpixels + (uv_pitch * ((vita_texture->h + 1) / 2)) + (UVrect.y * uv_pitch) + UVrect.x;
+
+        length = UVrect.w;
+
+        // U plane
+        if (length == uv_src_pitch && length == uv_pitch) {
+            SDL_memcpy(Udst, pixels, length*UVrect.h);
+        } else {
+            for (row = 0; row < UVrect.h; ++row) {
+                SDL_memcpy(Udst, pixels, length);
+                pixels += uv_src_pitch;
+                Udst += uv_pitch;
+            }
+        }
+
+        // V plane
+        if (length == uv_src_pitch && length == uv_pitch) {
+            SDL_memcpy(Vdst, pixels, length*UVrect.h);
+        } else {
+            for (row = 0; row < UVrect.h; ++row) {
+                SDL_memcpy(Vdst, pixels, length);
+                pixels += uv_src_pitch;
+                Vdst += uv_pitch;
+            }
+        }
+
+    } else if (vita_texture->nv12) {
+        void *UVdst;
+        int uv_pitch = 2 * ((dpitch+1) / 2);
+        int uv_src_pitch = 2 * ((pitch+1) / 2);
+        SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2 , (rect->h + 1) / 2};
+
+        // skip Y plane
+        void *Dpixels = (void *) ((Uint8 *) gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h));
+        UVdst = Dpixels + (UVrect.y * uv_pitch) + UVrect.x;
+
+        length = UVrect.w*2;
+
+        // UV plane
+        if (length == uv_src_pitch && length == uv_pitch) {
+            SDL_memcpy(UVdst, pixels, length*UVrect.h);
+        } else {
+            for (row = 0; row < UVrect.h; ++row) {
+                SDL_memcpy(UVdst, pixels, length);
+                pixels += uv_src_pitch;
+                UVdst += uv_pitch;
+            }
+        }
+    }
+#endif
+
     return 0;
 }
 
+#if SDL_HAVE_YUV
 static int
 VITA_GXM_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
     const SDL_Rect * rect,
@@ -345,9 +465,133 @@ VITA_GXM_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
     const Uint8 *Uplane, int Upitch,
     const Uint8 *Vplane, int Vpitch)
 {
+    Uint8 *dst;
+    int row, length, dpitch;
+    SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2};
+
+    VITA_GXM_SetYUVProfile(renderer, texture);
+
+    // copy Y plane
+    // obtain pixels via locking so that texture is flushed
+    VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch);
+
+    length = rect->w;
+
+    if (length == Ypitch && length == dpitch) {
+        SDL_memcpy(dst, Yplane, length*rect->h);
+    } else {
+        for (row = 0; row < rect->h; ++row) {
+            SDL_memcpy(dst, Yplane, length);
+            Yplane += Ypitch;
+            dst += dpitch;
+        }
+    }
+
+    // U/V planes
+    {
+        void *Udst;
+        void *Vdst;
+        VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) texture->driverdata;
+        int uv_pitch = (dpitch+1) / 2;
+
+        // skip Y plane
+        void *pixels = (void *) ((Uint8 *) gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h));
+
+        if (texture->format == SDL_PIXELFORMAT_YV12) { // YVU
+            Vdst = pixels + (UVrect.y * uv_pitch) + UVrect.x;
+            Udst = pixels + (uv_pitch * ((vita_texture->h + 1) / 2)) + (UVrect.y * uv_pitch) + UVrect.x;
+        } else { // YUV
+            Udst = pixels + (UVrect.y * uv_pitch) + UVrect.x;
+            Vdst = pixels + (uv_pitch * ((vita_texture->h + 1) / 2)) + (UVrect.y * uv_pitch) + UVrect.x;
+        }
+
+        length = UVrect.w;
+
+        // U plane
+        if (length == Upitch && length == uv_pitch) {
+            SDL_memcpy(Udst, Uplane, length*UVrect.h);
+        } else {
+            for (row = 0; row < UVrect.h; ++row) {
+                SDL_memcpy(Udst, Uplane, length);
+                Uplane += Upitch;
+                Udst += uv_pitch;
+            }
+        }
+
+        // V plane
+        if (length == Vpitch && length == uv_pitch) {
+            SDL_memcpy(Vdst, Vplane, length*UVrect.h);
+        } else {
+            for (row = 0; row < UVrect.h; ++row) {
+                SDL_memcpy(Vdst, Vplane, length);
+                Vplane += Vpitch;
+                Vdst += uv_pitch;
+            }
+        }
+
+    }
+
+    return 0;
+}
+
+static int
+VITA_GXM_UpdateTextureNV(SDL_Renderer * renderer, SDL_Texture * texture,
+    const SDL_Rect * rect,
+    const Uint8 *Yplane, int Ypitch,
+    const Uint8 *UVplane, int UVpitch)
+{
+
+    Uint8 *dst;
+    int row, length, dpitch;
+    SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2};
+
+    VITA_GXM_SetYUVProfile(renderer, texture);
+
+    // copy Y plane
+    VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch);
+
+    length = rect->w * SDL_BYTESPERPIXEL(texture->format);
+
+    if (length == Ypitch && length == dpitch) {
+      SDL_memcpy(dst, Yplane, length*rect->h);
+    } else {
+        for (row = 0; row < rect->h; ++row) {
+          SDL_memcpy(dst, Yplane, length);
+            Yplane += Ypitch;
+            dst += dpitch;
+        }
+    }
+
+    // UV plane
+    {
+        void *UVdst;
+        VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) texture->driverdata;
+        int uv_pitch = 2 * ((dpitch+1) / 2);
+
+        // skip Y plane
+        void *pixels = (void *) ((Uint8 *) gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h));
+
+        UVdst = pixels + (UVrect.y * uv_pitch) + UVrect.x;
+
+        length = UVrect.w * 2;
+
+        // UV plane
+        if (length == UVpitch && length == uv_pitch) {
+            SDL_memcpy(UVdst, UVplane, length*UVrect.h);
+        } else {
+            for (row = 0; row < UVrect.h; ++row) {
+                SDL_memcpy(UVdst, UVplane, length);
+                UVplane += UVpitch;
+                UVdst += uv_pitch;
+            }
+        }
+    }
+
     return 0;
 }
 
+#endif
+
 static int
 VITA_GXM_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
     const SDL_Rect *rect, void **pixels, int *pitch)
@@ -519,6 +763,7 @@ VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Textu
     size_indices = indices ? size_indices : 0;
 
     if (texture) {
+        VITA_GXM_TextureData* vita_texture = (VITA_GXM_TextureData*) texture->driverdata;
         texture_vertex *vertices;
 
         vertices = (texture_vertex *)pool_malloc(
@@ -551,7 +796,7 @@ VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Textu
 
             vertices[i].x = xy_[0] * scale_x;
             vertices[i].y = xy_[1] * scale_y;
-            vertices[i].u = uv_[0];
+            vertices[i].u = uv_[0] * vita_texture->wscale;
             vertices[i].v = uv_[1];
             vertices[i].color = col_;
         }
@@ -730,14 +975,6 @@ SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd)
     return 0;
 }
 
-static int
-SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd)
-{
-    VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
-
-    return SetDrawState(data, cmd);
-}
-
 static int
 VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
 {
@@ -824,11 +1061,7 @@ VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *
                     nextcmd = nextcmd->next;
                 }
 
-                if (thistexture) {
-                    ret = SetCopyState(renderer, cmd);
-                } else {
-                    ret = SetDrawState(data, cmd);
-                }
+                ret = SetDrawState(data, cmd);
 
                 if (ret == 0) {
                     int op = SCE_GXM_PRIMITIVE_TRIANGLES;
@@ -1013,7 +1246,7 @@ VITA_GXM_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture)
 
     sceGxmFinish(data->gxm_context);
 
-    free_gxm_texture(vita_texture->tex);
+    free_gxm_texture(data, vita_texture->tex);
 
     SDL_free(vita_texture);
 

+ 70 - 6
Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_memory.c

@@ -26,7 +26,7 @@
 #include "SDL_render_vita_gxm_memory.h"
 
 void *
-mem_gpu_alloc(SceKernelMemBlockType type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid)
+vita_mem_alloc(unsigned int type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid)
 {
     void *mem;
 
@@ -51,7 +51,7 @@ mem_gpu_alloc(SceKernelMemBlockType type, unsigned int size, unsigned int alignm
 }
 
 void
-mem_gpu_free(SceUID uid)
+vita_mem_free(SceUID uid)
 {
     void *mem = NULL;
     if (sceKernelGetMemBlockBase(uid, &mem) < 0)
@@ -61,7 +61,71 @@ mem_gpu_free(SceUID uid)
 }
 
 void *
-mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset)
+vita_gpu_mem_alloc(VITA_GXM_RenderData *data, unsigned int size)
+{
+    void *mem;
+
+    if (data->texturePool == NULL) {
+        int poolsize;
+        int ret;
+        SceKernelFreeMemorySizeInfo info;
+        info.size = sizeof(SceKernelFreeMemorySizeInfo);
+        sceKernelGetFreeMemorySize(&info);
+
+        poolsize = ALIGN(info.size_cdram, 256*1024);
+        if (poolsize > info.size_cdram) {
+            poolsize = ALIGN(info.size_cdram - 256*1024, 256*1024);
+        }
+        data->texturePoolUID = sceKernelAllocMemBlock("gpu_texture_pool", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, poolsize, NULL);
+        if (data->texturePoolUID < 0) {
+            return NULL;
+        }
+
+        ret = sceKernelGetMemBlockBase(data->texturePoolUID, &mem);
+        if ( ret < 0)
+        {
+            return NULL;
+        }
+        data->texturePool = sceClibMspaceCreate(mem, poolsize);
+
+        if (data->texturePool == NULL) {
+            return NULL;
+        }
+        ret = sceGxmMapMemory(mem, poolsize, SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE);
+        if (ret < 0)
+        {
+            return NULL;
+        }
+    }
+    return sceClibMspaceMemalign(data->texturePool, SCE_GXM_TEXTURE_ALIGNMENT, size);
+}
+
+void
+vita_gpu_mem_free(VITA_GXM_RenderData *data, void* ptr)
+{
+    if (data->texturePool != NULL)
+    {
+        sceClibMspaceFree(data->texturePool, ptr);
+    }
+}
+
+void
+vita_gpu_mem_destroy(VITA_GXM_RenderData *data)
+{
+    void *mem = NULL;
+    if (data->texturePool != NULL)
+    {
+        sceClibMspaceDestroy(data->texturePool);
+        data->texturePool = NULL;
+        if (sceKernelGetMemBlockBase(data->texturePoolUID, &mem) < 0)
+            return;
+        sceGxmUnmapMemory(mem);
+        sceKernelFreeMemBlock(data->texturePoolUID);
+    }
+}
+
+void *
+vita_mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset)
 {
     void *mem = NULL;
 
@@ -77,7 +141,7 @@ mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset)
 }
 
 void
-mem_vertex_usse_free(SceUID uid)
+vita_mem_vertex_usse_free(SceUID uid)
 {
     void *mem = NULL;
     if (sceKernelGetMemBlockBase(uid, &mem) < 0)
@@ -87,7 +151,7 @@ mem_vertex_usse_free(SceUID uid)
 }
 
 void *
-mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset)
+vita_mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset)
 {
     void *mem = NULL;
 
@@ -103,7 +167,7 @@ mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offse
 }
 
 void
-mem_fragment_usse_free(SceUID uid)
+vita_mem_fragment_usse_free(SceUID uid)
 {
     void *mem = NULL;
     if (sceKernelGetMemBlockBase(uid, &mem) < 0)

+ 10 - 6
Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_memory.h

@@ -25,15 +25,19 @@
 #include <psp2/gxm.h>
 #include <psp2/types.h>
 #include <psp2/kernel/sysmem.h>
+#include "SDL_render_vita_gxm_types.h"
 
 #define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
 
-void *mem_gpu_alloc(SceKernelMemBlockType type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid);
-void mem_gpu_free(SceUID uid);
-void *mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset);
-void mem_vertex_usse_free(SceUID uid);
-void *mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset);
-void mem_fragment_usse_free(SceUID uid);
+void *vita_mem_alloc(unsigned int type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid);
+void vita_mem_free(SceUID uid);
+void *vita_gpu_mem_alloc(VITA_GXM_RenderData *data, unsigned int size);
+void vita_gpu_mem_free(VITA_GXM_RenderData *data, void* ptr);
+void vita_gpu_mem_destroy(VITA_GXM_RenderData *data);
+void *vita_mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset);
+void vita_mem_vertex_usse_free(SceUID uid);
+void *vita_mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset);
+void vita_mem_fragment_usse_free(SceUID uid);
 
 #endif /* SDL_RENDER_VITA_GXM_MEMORY_H */
 

+ 82 - 70
Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_tools.c

@@ -117,6 +117,8 @@ tex_format_to_bytespp(SceGxmTextureFormat format)
     case SCE_GXM_TEXTURE_BASE_FORMAT_U8:
     case SCE_GXM_TEXTURE_BASE_FORMAT_S8:
     case SCE_GXM_TEXTURE_BASE_FORMAT_P8:
+    case SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P2: // YUV actually uses 12 bits per pixel. UV planes bits/mem are handled elsewhere
+    case SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3:
         return 1;
     case SCE_GXM_TEXTURE_BASE_FORMAT_U4U4U4U4:
     case SCE_GXM_TEXTURE_BASE_FORMAT_U8U3U3U2:
@@ -414,28 +416,28 @@ gxm_init(SDL_Renderer *renderer)
     }
 
     // allocate ring buffer memory using default sizes
-    vdmRingBuffer = mem_gpu_alloc(
+    vdmRingBuffer = vita_mem_alloc(
         SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
         SCE_GXM_DEFAULT_VDM_RING_BUFFER_SIZE,
         4,
         SCE_GXM_MEMORY_ATTRIB_READ,
         &data->vdmRingBufferUid);
 
-    vertexRingBuffer = mem_gpu_alloc(
+    vertexRingBuffer = vita_mem_alloc(
         SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
         SCE_GXM_DEFAULT_VERTEX_RING_BUFFER_SIZE,
         4,
         SCE_GXM_MEMORY_ATTRIB_READ,
         &data->vertexRingBufferUid);
 
-    fragmentRingBuffer = mem_gpu_alloc(
+    fragmentRingBuffer = vita_mem_alloc(
         SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
         SCE_GXM_DEFAULT_FRAGMENT_RING_BUFFER_SIZE,
         4,
         SCE_GXM_MEMORY_ATTRIB_READ,
         &data->fragmentRingBufferUid);
 
-    fragmentUsseRingBuffer = mem_fragment_usse_alloc(
+    fragmentUsseRingBuffer = vita_mem_fragment_usse_alloc(
         SCE_GXM_DEFAULT_FRAGMENT_USSE_RING_BUFFER_SIZE,
         &data->fragmentUsseRingBufferUid,
         &fragmentUsseRingBufferOffset);
@@ -480,7 +482,7 @@ gxm_init(SDL_Renderer *renderer)
     for (i = 0; i < VITA_GXM_BUFFERS; i++) {
 
         // allocate memory for display
-        data->displayBufferData[i] = mem_gpu_alloc(
+        data->displayBufferData[i] = vita_mem_alloc(
             SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW,
             4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT,
             SCE_GXM_COLOR_SURFACE_ALIGNMENT,
@@ -525,7 +527,7 @@ gxm_init(SDL_Renderer *renderer)
 
 
     // allocate the depth buffer
-    data->depthBufferData = mem_gpu_alloc(
+    data->depthBufferData = vita_mem_alloc(
         SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
         4 * sampleCount,
         SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT,
@@ -533,7 +535,7 @@ gxm_init(SDL_Renderer *renderer)
         &data->depthBufferUid);
 
     // allocate the stencil buffer
-    data->stencilBufferData = mem_gpu_alloc(
+    data->stencilBufferData = vita_mem_alloc(
         SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
         4 * sampleCount,
         SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT,
@@ -565,19 +567,19 @@ gxm_init(SDL_Renderer *renderer)
 
 
     // allocate memory for buffers and USSE code
-    patcherBuffer = mem_gpu_alloc(
+    patcherBuffer = vita_mem_alloc(
         SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
         patcherBufferSize,
         4,
         SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
         &data->patcherBufferUid);
 
-    patcherVertexUsse = mem_vertex_usse_alloc(
+    patcherVertexUsse = vita_mem_vertex_usse_alloc(
         patcherVertexUsseSize,
         &data->patcherVertexUsseUid,
         &patcherVertexUsseOffset);
 
-    patcherFragmentUsse = mem_fragment_usse_alloc(
+    patcherFragmentUsse = vita_mem_fragment_usse_alloc(
         patcherFragmentUsseSize,
         &data->patcherFragmentUsseUid,
         &patcherFragmentUsseOffset);
@@ -728,7 +730,7 @@ gxm_init(SDL_Renderer *renderer)
         }
 
         // create the clear triangle vertex/index data
-        data->clearVertices = (clear_vertex *)mem_gpu_alloc(
+        data->clearVertices = (clear_vertex *)vita_mem_alloc(
             SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
             3*sizeof(clear_vertex),
             4,
@@ -740,7 +742,7 @@ gxm_init(SDL_Renderer *renderer)
     // Allocate a 64k * 2 bytes = 128 KiB buffer and store all possible
     // 16-bit indices in linear ascending order, so we can use this for
     // all drawing operations where we don't want to use indexing.
-    data->linearIndices = (uint16_t *)mem_gpu_alloc(
+    data->linearIndices = (uint16_t *)vita_mem_alloc(
         SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
         UINT16_MAX*sizeof(uint16_t),
         sizeof(uint16_t),
@@ -871,7 +873,7 @@ gxm_init(SDL_Renderer *renderer)
     data->textureWvpParam = (SceGxmProgramParameter *)sceGxmProgramFindParameterByName(textureVertexProgramGxp, "wvp");
 
     // Allocate memory for the memory pool
-    data->pool_addr[0] = mem_gpu_alloc(
+    data->pool_addr[0] = vita_mem_alloc(
         SCE_KERNEL_MEMBLOCK_TYPE_USER_RW,
         VITA_GXM_POOL_SIZE,
         sizeof(void *),
@@ -879,7 +881,7 @@ gxm_init(SDL_Renderer *renderer)
         &data->poolUid[0]
     );
 
-    data->pool_addr[1] = mem_gpu_alloc(
+    data->pool_addr[1] = vita_mem_alloc(
         SCE_KERNEL_MEMBLOCK_TYPE_USER_RW,
         VITA_GXM_POOL_SIZE,
         sizeof(void *),
@@ -918,28 +920,28 @@ void gxm_finish(SDL_Renderer *renderer)
     free_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_mod);
     free_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_mul);
 
-    mem_gpu_free(data->linearIndicesUid);
-    mem_gpu_free(data->clearVerticesUid);
+    vita_mem_free(data->linearIndicesUid);
+    vita_mem_free(data->clearVerticesUid);
 
     // wait until display queue is finished before deallocating display buffers
     sceGxmDisplayQueueFinish();
 
     // clean up display queue
-    mem_gpu_free(data->depthBufferUid);
+    vita_mem_free(data->depthBufferUid);
 
     for (size_t i = 0; i < VITA_GXM_BUFFERS; i++)
     {
         // clear the buffer then deallocate
         SDL_memset(data->displayBufferData[i], 0, VITA_GXM_SCREEN_HEIGHT * VITA_GXM_SCREEN_STRIDE * 4);
-        mem_gpu_free(data->displayBufferUid[i]);
+        vita_mem_free(data->displayBufferUid[i]);
 
         // destroy the sync object
         sceGxmSyncObjectDestroy(data->displayBufferSync[i]);
     }
 
     // Free the depth and stencil buffer
-    mem_gpu_free(data->depthBufferUid);
-    mem_gpu_free(data->stencilBufferUid);
+    vita_mem_free(data->depthBufferUid);
+    vita_mem_free(data->stencilBufferUid);
 
     // unregister programs and destroy shader patcher
     sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->clearFragmentProgramId);
@@ -950,23 +952,24 @@ void gxm_finish(SDL_Renderer *renderer)
     sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->textureVertexProgramId);
 
     sceGxmShaderPatcherDestroy(data->shaderPatcher);
-    mem_fragment_usse_free(data->patcherFragmentUsseUid);
-    mem_vertex_usse_free(data->patcherVertexUsseUid);
-    mem_gpu_free(data->patcherBufferUid);
+    vita_mem_fragment_usse_free(data->patcherFragmentUsseUid);
+    vita_mem_vertex_usse_free(data->patcherVertexUsseUid);
+    vita_mem_free(data->patcherBufferUid);
 
     // destroy the render target
     sceGxmDestroyRenderTarget(data->renderTarget);
 
     // destroy the gxm context
     sceGxmDestroyContext(data->gxm_context);
-    mem_fragment_usse_free(data->fragmentUsseRingBufferUid);
-    mem_gpu_free(data->fragmentRingBufferUid);
-    mem_gpu_free(data->vertexRingBufferUid);
-    mem_gpu_free(data->vdmRingBufferUid);
+    vita_mem_fragment_usse_free(data->fragmentUsseRingBufferUid);
+    vita_mem_free(data->fragmentRingBufferUid);
+    vita_mem_free(data->vertexRingBufferUid);
+    vita_mem_free(data->vdmRingBufferUid);
     SDL_free(data->contextParams.hostMem);
 
-    mem_gpu_free(data->poolUid[0]);
-    mem_gpu_free(data->poolUid[1]);
+    vita_mem_free(data->poolUid[0]);
+    vita_mem_free(data->poolUid[1]);
+    vita_gpu_mem_destroy(data);
 
     // terminate libgxm
     sceGxmTerminate();
@@ -975,16 +978,20 @@ void gxm_finish(SDL_Renderer *renderer)
 // textures
 
 void
-free_gxm_texture(gxm_texture *texture)
+free_gxm_texture(VITA_GXM_RenderData *data, gxm_texture *texture)
 {
     if (texture) {
         if (texture->gxm_rendertarget) {
             sceGxmDestroyRenderTarget(texture->gxm_rendertarget);
         }
         if (texture->depth_UID) {
-            mem_gpu_free(texture->depth_UID);
+            vita_mem_free(texture->depth_UID);
+        }
+        if (texture->cdram) {
+            vita_gpu_mem_free(data, sceGxmTextureGetData(&texture->gxm_tex));
+        } else {
+            vita_mem_free(texture->data_UID);
         }
-        mem_gpu_free(texture->data_UID);
         SDL_free(texture);
     }
 }
@@ -995,25 +1002,6 @@ gxm_texture_get_format(const gxm_texture *texture)
     return sceGxmTextureGetFormat(&texture->gxm_tex);
 }
 
-unsigned int
-gxm_texture_get_width(const gxm_texture *texture)
-{
-    return sceGxmTextureGetWidth(&texture->gxm_tex);
-}
-
-unsigned int
-gxm_texture_get_height(const gxm_texture *texture)
-{
-    return sceGxmTextureGetHeight(&texture->gxm_tex);
-}
-
-unsigned int
-gxm_texture_get_stride(const gxm_texture *texture)
-{
-    return ((gxm_texture_get_width(texture) + 7) & ~7)
-        * tex_format_to_bytespp(gxm_texture_get_format(texture));
-}
-
 void *
 gxm_texture_get_datap(const gxm_texture *texture)
 {
@@ -1021,34 +1009,53 @@ gxm_texture_get_datap(const gxm_texture *texture)
 }
 
 gxm_texture *
-create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget)
+create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget, unsigned int *return_w, unsigned int *return_h, unsigned int *return_pitch, float *return_wscale)
 {
     gxm_texture *texture = SDL_calloc(1, sizeof(gxm_texture));
-    const int tex_size =  ((w + 7) & ~ 7) * h * tex_format_to_bytespp(format);
+    int aligned_w = ALIGN(w, 8);
+    int texture_w = w;
+    int tex_size =  aligned_w * h * tex_format_to_bytespp(format);
     void *texture_data;
+    int ret;
+
+    *return_wscale = 1.0f;
+
+    // SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3/P2 based formats require width aligned to 16
+    if ( (format & 0x9f000000U) == SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3 || (format & 0x9f000000U) == SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P2) {
+        aligned_w = ALIGN(w, 16);
+        texture_w = aligned_w;
+        tex_size =  aligned_w * h * tex_format_to_bytespp(format);
+        *return_wscale = (float) (w) / texture_w;
+        // add storage for UV planes
+        tex_size += (((aligned_w + 1) / 2) * ((h + 1) / 2)) * 2;
+    }
 
     if (!texture)
         return NULL;
 
+    *return_w = w;
+    *return_h = h;
+    *return_pitch = aligned_w * tex_format_to_bytespp(format);
+
     /* Allocate a GPU buffer for the texture */
-    texture_data = mem_gpu_alloc(
-        SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW,
-        tex_size,
-        SCE_GXM_TEXTURE_ALIGNMENT,
-        SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
-        &texture->data_UID
+    texture_data = vita_gpu_mem_alloc(
+        data,
+        tex_size
     );
 
     /* Try SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE in case we're out of VRAM */
     if (!texture_data) {
         SDL_LogWarn(SDL_LOG_CATEGORY_RENDER, "CDRAM texture allocation failed\n");
-        texture_data = mem_gpu_alloc(
+        texture_data = vita_mem_alloc(
             SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
             tex_size,
             SCE_GXM_TEXTURE_ALIGNMENT,
             SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
             &texture->data_UID
         );
+        texture->cdram = 0;
+    } else {
+        texture->cdram = 1;
     }
 
     if (!texture_data) {
@@ -1060,7 +1067,12 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
     SDL_memset(texture_data, 0, tex_size);
 
     /* Create the gxm texture */
-    sceGxmTextureInitLinear( &texture->gxm_tex, texture_data, format, w, h, 0);
+    ret = sceGxmTextureInitLinear( &texture->gxm_tex, texture_data, format, texture_w, h, 0);
+    if (ret < 0) {
+      free_gxm_texture(data, texture);
+      SDL_LogError(SDL_LOG_CATEGORY_RENDER, "texture init failed: %x\n", ret);
+      return NULL;
+    }
 
     if (isRenderTarget) {
         void *depthBufferData;
@@ -1083,13 +1095,13 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
         );
 
         if (err < 0) {
-            free_gxm_texture(texture);
-            SDL_LogError(SDL_LOG_CATEGORY_RENDER, "color surface init failed: %d\n", err);
+            free_gxm_texture(data, texture);
+            SDL_LogError(SDL_LOG_CATEGORY_RENDER, "color surface init failed: %x\n", err);
             return NULL;
         }
 
         // allocate it
-        depthBufferData = mem_gpu_alloc(
+        depthBufferData = vita_mem_alloc(
             SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
             4*sampleCount,
             SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT,
@@ -1106,8 +1118,8 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
             NULL);
 
         if (err < 0) {
-            free_gxm_texture(texture);
-            SDL_LogError(SDL_LOG_CATEGORY_RENDER, "depth stencil init failed: %d\n", err);
+            free_gxm_texture(data, texture);
+            SDL_LogError(SDL_LOG_CATEGORY_RENDER, "depth stencil init failed: %x\n", err);
             return NULL;
         }
 
@@ -1131,8 +1143,8 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
             texture->gxm_rendertarget = tgt;
 
             if (err < 0) {
-                free_gxm_texture(texture);
-                SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create render target failed: %d\n", err);
+                free_gxm_texture(data, texture);
+                SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create render target failed: %x\n", err);
                 return NULL;
             }
         }
@@ -1181,7 +1193,7 @@ void gxm_init_for_common_dialog(void)
     for (int i = 0; i < VITA_GXM_BUFFERS; i += 1)
     {
         buffer_for_common_dialog[i].displayData.wait_vblank = SDL_TRUE;
-        buffer_for_common_dialog[i].displayData.address = mem_gpu_alloc(
+        buffer_for_common_dialog[i].displayData.address = vita_mem_alloc(
             SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW,
             4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT,
             SCE_GXM_COLOR_SURFACE_ALIGNMENT,
@@ -1229,7 +1241,7 @@ void gxm_term_for_common_dialog(void)
     sceGxmDisplayQueueFinish();
     for (int i = 0; i < VITA_GXM_BUFFERS; i += 1)
     {
-        mem_gpu_free(buffer_for_common_dialog[i].uid);
+        vita_mem_free(buffer_for_common_dialog[i].uid);
         sceGxmSyncObjectDestroy(buffer_for_common_dialog[i].sync);
     }
 }

+ 2 - 5
Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_tools.h

@@ -48,15 +48,12 @@ void unset_clip_rectangle(VITA_GXM_RenderData *data);
 int gxm_init(SDL_Renderer *renderer);
 void gxm_finish(SDL_Renderer *renderer);
 
-gxm_texture *create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget);
-void free_gxm_texture(gxm_texture *texture);
+gxm_texture *create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget, unsigned int *return_w, unsigned int *return_h, unsigned int *return_pitch, float *return_wscale);
+void free_gxm_texture(VITA_GXM_RenderData *data, gxm_texture *texture);
 
 void gxm_texture_set_filters(gxm_texture *texture, SceGxmTextureFilter min_filter, SceGxmTextureFilter mag_filter);
 SceGxmTextureFormat gxm_texture_get_format(const gxm_texture *texture);
 
-unsigned int gxm_texture_get_width(const gxm_texture *texture);
-unsigned int gxm_texture_get_height(const gxm_texture *texture);
-unsigned int gxm_texture_get_stride(const gxm_texture *texture);
 void *gxm_texture_get_datap(const gxm_texture *texture);
 
 void gxm_minimal_init_for_common_dialog(void);

+ 10 - 3
Engine/lib/sdl/src/render/vitagxm/SDL_render_vita_gxm_types.h

@@ -33,6 +33,7 @@
 #include <psp2/gxm.h>
 #include <psp2/types.h>
 #include <psp2/kernel/sysmem.h>
+#include <psp2/kernel/clib.h>
 
 #include <string.h>
 
@@ -79,6 +80,7 @@ typedef struct gxm_texture {
     SceGxmColorSurface gxm_colorsurface;
     SceGxmDepthStencilSurface gxm_depthstencil;
     SceUID depth_UID;
+    SDL_bool cdram;
 } gxm_texture;
 
 typedef struct fragment_programs {
@@ -186,14 +188,19 @@ typedef struct
     blend_fragment_programs blendFragmentPrograms;
 
     gxm_drawstate_cache drawstate;
+    SceClibMspace texturePool;
+    SceUID texturePoolUID;
 } VITA_GXM_RenderData;
 
 typedef struct
 {
     gxm_texture  *tex;
-    unsigned int    pitch;
-    unsigned int    w;
-    unsigned int    h;
+    unsigned int pitch;
+    unsigned int w;
+    unsigned int h;
+    float wscale;
+    SDL_bool     yuv;
+    SDL_bool     nv12;
 } VITA_GXM_TextureData;
 
 #endif /* SDL_RENDER_VITA_GXM_TYPES_H */

+ 2 - 0
Engine/lib/sdl/src/test/SDL_test_common.c

@@ -1464,10 +1464,12 @@ default: return "???";
 static void
 SDLTest_PrintEvent(SDL_Event * event)
 {
+#ifndef VERBOSE_MOTION_EVENTS
     if ((event->type == SDL_MOUSEMOTION) || (event->type == SDL_FINGERMOTION)) {
         /* Mouse and finger motion are really spammy */
         return;
     }
+#endif
 
     switch (event->type) {
     case SDL_DISPLAYEVENT:

+ 5 - 5
Engine/lib/sdl/src/thread/os2/SDL_sysmutex.c

@@ -56,12 +56,12 @@ SDL_CreateMutex(void)
 void
 SDL_DestroyMutex(SDL_mutex * mutex)
 {
-    ULONG ulRC;
     HMTX  hMtx = (HMTX)mutex;
-
-    ulRC = DosCloseMutexSem(hMtx);
-    if (ulRC != NO_ERROR) {
-        debug_os2("DosCloseMutexSem(), rc = %u", ulRC);
+    if (hMtx != NULLHANDLE) {
+        const ULONG ulRC = DosCloseMutexSem(hMtx);
+        if (ulRC != NO_ERROR) {
+            debug_os2("DosCloseMutexSem(), rc = %u", ulRC);
+        }
     }
 }
 

+ 11 - 2
Engine/lib/sdl/src/timer/os2/SDL_systimer.c

@@ -39,6 +39,7 @@
 
 typedef unsigned long long  ULLONG;
 
+static SDL_bool ticks_started = SDL_FALSE;
 static ULONG    ulTmrFreq = 0;
 static ULLONG   ullTmrStart = 0;
 
@@ -46,7 +47,14 @@ void
 SDL_TicksInit(void)
 {
     ULONG ulTmrStart;  /* for 32-bit fallback. */
-    ULONG ulRC = DosTmrQueryFreq(&ulTmrFreq);
+    ULONG ulRC;
+
+    if (ticks_started) {
+        return;
+    }
+    ticks_started = SDL_TRUE;
+
+    ulRC = DosTmrQueryFreq(&ulTmrFreq);
     if (ulRC != NO_ERROR) {
         debug_os2("DosTmrQueryFreq() failed, rc = %u", ulRC);
     } else {
@@ -65,6 +73,7 @@ SDL_TicksInit(void)
 void
 SDL_TicksQuit(void)
 {
+    ticks_started = SDL_FALSE;
 }
 
 Uint64
@@ -73,7 +82,7 @@ SDL_GetTicks64(void)
     Uint64 ui64Result;
     ULLONG ullTmrNow;
 
-    if (ulTmrFreq == 0) { /* Was not initialized. */
+    if (!ticks_started) {
         SDL_TicksInit();
     }
 

+ 6 - 0
Engine/lib/sdl/src/video/SDL_bmp.c

@@ -412,6 +412,12 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc)
             goto done;
         }
 
+        if (biBitCount >= 32) {  /* we shift biClrUsed by this value later. */
+            SDL_SetError("Unsupported or incorrect biBitCount field");
+            was_error = SDL_TRUE;
+            goto done;
+        }
+
         if (biClrUsed == 0) {
             biClrUsed = 1 << biBitCount;
         }

+ 3 - 4
Engine/lib/sdl/src/video/SDL_egl.c

@@ -27,7 +27,6 @@
 #endif
 #if SDL_VIDEO_DRIVER_ANDROID
 #include <android/native_window.h>
-#include "../core/android/SDL_android.h"
 #include "../video/android/SDL_androidvideo.h"
 #endif
 #if SDL_VIDEO_DRIVER_RPI
@@ -99,7 +98,7 @@
 #define DEFAULT_OGL_ES "libGLESv1_CM.so.1"
 #endif /* SDL_VIDEO_DRIVER_RPI */
 
-#if SDL_VIDEO_OPENGL
+#if SDL_VIDEO_OPENGL && !SDL_VIDEO_VITA_PVR_OGL
 #include "SDL_opengl.h"
 #endif
 
@@ -530,7 +529,7 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa
     }
 #endif
     /* Try the implementation-specific eglGetDisplay even if eglGetPlatformDisplay fails */
-    if (_this->egl_data->egl_display == EGL_NO_DISPLAY) {
+    if ((_this->egl_data->egl_display == EGL_NO_DISPLAY) && (_this->egl_data->eglGetDisplay != NULL)) {
         _this->egl_data->egl_display = _this->egl_data->eglGetDisplay(native_display);
     }
     if (_this->egl_data->egl_display == EGL_NO_DISPLAY) {
@@ -1062,7 +1061,7 @@ SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface)
             if (SDL_GL_ExtensionSupported("GL_OES_surfaceless_context")) {
                 _this->gl_allow_no_surface = SDL_TRUE;
             }
-#if SDL_VIDEO_OPENGL
+#if SDL_VIDEO_OPENGL && !defined(SDL_VIDEO_DRIVER_VITA)
         } else {
             /* Desktop OpenGL supports it by default from version 3.0 on. */
             void (APIENTRY * glGetIntegervFunc) (GLenum pname, GLint * params);

+ 1 - 40
Engine/lib/sdl/src/video/SDL_pixels.c

@@ -28,6 +28,7 @@
 #include "SDL_blit.h"
 #include "SDL_pixels_c.h"
 #include "SDL_RLEaccel_c.h"
+#include "../SDL_list.h"
 
 
 /* Lookup tables to expand partial bytes to the full 0..255 range */
@@ -1024,12 +1025,6 @@ SDL_AllocBlitMap(void)
 }
 
 
-typedef struct SDL_ListNode
-{
-    void *entry;
-    struct SDL_ListNode *next;
-} SDL_ListNode;
-
 void
 SDL_InvalidateAllBlitMap(SDL_Surface *surface)
 {
@@ -1045,40 +1040,6 @@ SDL_InvalidateAllBlitMap(SDL_Surface *surface)
     }
 }
 
-static void SDL_ListAdd(SDL_ListNode **head, void *ent);
-static void SDL_ListRemove(SDL_ListNode **head, void *ent);
-
-void
-SDL_ListAdd(SDL_ListNode **head, void *ent)
-{
-    SDL_ListNode *node = SDL_malloc(sizeof (*node));
-
-    if (node == NULL) {
-        SDL_OutOfMemory();
-        return;
-    }
-
-    node->entry = ent;
-    node->next = *head;
-    *head = node;
-}
-
-void
-SDL_ListRemove(SDL_ListNode **head, void *ent)
-{
-    SDL_ListNode **ptr = head;
-
-    while (*ptr) {
-        if ((*ptr)->entry == ent) {
-            SDL_ListNode *tmp = *ptr;
-            *ptr = (*ptr)->next;
-            SDL_free(tmp);
-            return;
-        }
-        ptr = &(*ptr)->next;
-    }
-}
-
 void
 SDL_InvalidateMap(SDL_BlitMap * map)
 {

+ 1 - 0
Engine/lib/sdl/src/video/SDL_sysvideo.h

@@ -345,6 +345,7 @@ struct SDL_VideoDevice
     Uint32 next_object_id;
     char *clipboard_text;
     SDL_bool setting_display_mode;
+    SDL_bool disable_display_mode_switching;
 
     /* * * */
     /* Data used by the GL drivers */

+ 32 - 22
Engine/lib/sdl/src/video/SDL_video.c

@@ -61,12 +61,12 @@ static VideoBootStrap *bootstrap[] = {
 #if SDL_VIDEO_DRIVER_COCOA
     &COCOA_bootstrap,
 #endif
-#if SDL_VIDEO_DRIVER_WAYLAND
-    &Wayland_bootstrap,
-#endif
 #if SDL_VIDEO_DRIVER_X11
     &X11_bootstrap,
 #endif
+#if SDL_VIDEO_DRIVER_WAYLAND
+    &Wayland_bootstrap,
+#endif
 #if SDL_VIDEO_DRIVER_VIVANTE
     &VIVANTE_bootstrap,
 #endif
@@ -261,6 +261,7 @@ SDL_CreateWindowTexture(SDL_VideoDevice *_this, SDL_Window * window, Uint32 * fo
                                       SDL_TEXTUREACCESS_STREAMING,
                                       window->w, window->h);
     if (!data->texture) {
+        /* codechecker_false_positive [Malloc] Static analyzer doesn't realize allocated `data` is saved to SDL_WINDOWTEXTUREDATA and not leaked here. */
         return -1;
     }
 
@@ -424,7 +425,7 @@ SDL_VideoInit(const char *driver_name)
     i = index = 0;
     video = NULL;
     if (driver_name == NULL) {
-        driver_name = SDL_getenv("SDL_VIDEODRIVER");
+        driver_name = SDL_GetHint(SDL_HINT_VIDEODRIVER);
     }
     if (driver_name != NULL && *driver_name != 0) {
         const char *driver_attempt = driver_name;
@@ -1184,6 +1185,7 @@ SDL_GetWindowDisplayMode(SDL_Window * window, SDL_DisplayMode * mode)
     } else if (!SDL_GetClosestDisplayModeForDisplay(SDL_GetDisplayForWindow(window),
                                              &fullscreen_mode,
                                              &fullscreen_mode)) {
+        SDL_zerop(mode);
         return SDL_SetError("Couldn't find display mode match");
     }
 
@@ -1337,14 +1339,17 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen)
                     resized = SDL_FALSE;
                 }
 
-                /* only do the mode change if we want exclusive fullscreen */
-                if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) {
-                    if (SDL_SetDisplayModeForDisplay(display, &fullscreen_mode) < 0) {
-                        return -1;
-                    }
-                } else {
-                    if (SDL_SetDisplayModeForDisplay(display, NULL) < 0) {
-                        return -1;
+                /* Don't try to change the display mode if the driver doesn't want it. */
+                if (_this->disable_display_mode_switching == SDL_FALSE) {
+                    /* only do the mode change if we want exclusive fullscreen */
+                    if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) {
+                        if (SDL_SetDisplayModeForDisplay(display, &fullscreen_mode) < 0) {
+                            return -1;
+                        }
+                    } else {
+                        if (SDL_SetDisplayModeForDisplay(display, NULL) < 0) {
+                            return -1;
+                        }
                     }
                 }
 
@@ -3055,7 +3060,8 @@ ShouldMinimizeOnFocusLoss(SDL_Window * window)
     /* Real fullscreen windows should minimize on focus loss so the desktop video mode is restored */
     hint = SDL_GetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS);
     if (!hint || !*hint || SDL_strcasecmp(hint, "auto") == 0) {
-        if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) {
+        if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP ||
+            _this->disable_display_mode_switching == SDL_TRUE) {
             return SDL_FALSE;
         } else {
             return SDL_TRUE;
@@ -3919,6 +3925,10 @@ SDL_GL_MakeCurrent(SDL_Window * window, SDL_GLContext ctx)
 {
     int retval;
 
+    if (!_this) {
+        return SDL_UninitializedVideo();
+    }
+
     if (window == SDL_GL_GetCurrentWindow() &&
         ctx == SDL_GL_GetCurrentContext()) {
         /* We're already current. */
@@ -4262,12 +4272,12 @@ SDL_IsScreenKeyboardShown(SDL_Window *window)
 #if SDL_VIDEO_DRIVER_UIKIT
 #include "uikit/SDL_uikitmessagebox.h"
 #endif
-#if SDL_VIDEO_DRIVER_WAYLAND
-#include "wayland/SDL_waylandmessagebox.h"
-#endif
 #if SDL_VIDEO_DRIVER_X11
 #include "x11/SDL_x11messagebox.h"
 #endif
+#if SDL_VIDEO_DRIVER_WAYLAND
+#include "wayland/SDL_waylandmessagebox.h"
+#endif
 #if SDL_VIDEO_DRIVER_HAIKU
 #include "haiku/SDL_bmessagebox.h"
 #endif
@@ -4375,17 +4385,17 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
         retval = 0;
     }
 #endif
-#if SDL_VIDEO_DRIVER_WAYLAND
+#if SDL_VIDEO_DRIVER_X11
     if (retval == -1 &&
-        SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_WAYLAND) &&
-        Wayland_ShowMessageBox(messageboxdata, buttonid) == 0) {
+        SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_X11) &&
+        X11_ShowMessageBox(messageboxdata, buttonid) == 0) {
         retval = 0;
     }
 #endif
-#if SDL_VIDEO_DRIVER_X11
+#if SDL_VIDEO_DRIVER_WAYLAND
     if (retval == -1 &&
-        SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_X11) &&
-        X11_ShowMessageBox(messageboxdata, buttonid) == 0) {
+        SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_WAYLAND) &&
+        Wayland_ShowMessageBox(messageboxdata, buttonid) == 0) {
         retval = 0;
     }
 #endif

+ 1 - 0
Engine/lib/sdl/src/video/android/SDL_androidvideo.c

@@ -122,6 +122,7 @@ Android_CreateDevice(int devindex)
     device->SetWindowTitle = Android_SetWindowTitle;
     device->SetWindowFullscreen = Android_SetWindowFullscreen;
     device->MinimizeWindow = Android_MinimizeWindow;
+    device->SetWindowResizable = Android_SetWindowResizable;
     device->DestroyWindow = Android_DestroyWindow;
     device->GetWindowWMInfo = Android_GetWindowWMInfo;
 

+ 6 - 0
Engine/lib/sdl/src/video/android/SDL_androidwindow.c

@@ -167,6 +167,12 @@ Android_MinimizeWindow(_THIS, SDL_Window *window)
     Android_JNI_MinizeWindow();
 }
 
+void Android_SetWindowResizable(_THIS, SDL_Window *window, SDL_bool resizable)
+{
+    /* Set orientation */
+    Android_JNI_SetOrientation(window->w, window->h, window->flags & SDL_WINDOW_RESIZABLE, SDL_GetHint(SDL_HINT_ORIENTATIONS));
+}
+
 void
 Android_DestroyWindow(_THIS, SDL_Window *window)
 {

+ 1 - 0
Engine/lib/sdl/src/video/android/SDL_androidwindow.h

@@ -30,6 +30,7 @@ extern int Android_CreateWindow(_THIS, SDL_Window *window);
 extern void Android_SetWindowTitle(_THIS, SDL_Window *window);
 extern void Android_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
 extern void Android_MinimizeWindow(_THIS, SDL_Window *window);
+extern void Android_SetWindowResizable(_THIS, SDL_Window *window, SDL_bool resizable);
 
 extern void Android_DestroyWindow(_THIS, SDL_Window *window);
 extern SDL_bool Android_GetWindowWMInfo(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info);

+ 2 - 1
Engine/lib/sdl/src/video/dummy/SDL_nullvideo.c

@@ -46,6 +46,7 @@
 #include "SDL_nullvideo.h"
 #include "SDL_nullevents_c.h"
 #include "SDL_nullframebuffer_c.h"
+#include "SDL_hints.h"
 
 #define DUMMYVID_DRIVER_NAME "dummy"
 
@@ -59,7 +60,7 @@ static void DUMMY_VideoQuit(_THIS);
 static int
 DUMMY_Available(void)
 {
-    const char *envr = SDL_getenv("SDL_VIDEODRIVER");
+    const char *envr = SDL_GetHint(SDL_HINT_VIDEODRIVER);
     if ((envr) && (SDL_strcmp(envr, DUMMYVID_DRIVER_NAME) == 0)) {
         return (1);
     }

+ 27 - 11
Engine/lib/sdl/src/video/emscripten/SDL_emscriptenframebuffer.c

@@ -26,6 +26,8 @@
 #include "SDL_emscriptenframebuffer.h"
 #include "SDL_hints.h"
 
+#include <emscripten/threading.h>
+
 
 int Emscripten_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch)
 {
@@ -57,18 +59,9 @@ int Emscripten_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * form
     return 0;
 }
 
-int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects)
+static void
+Emscripten_UpdateWindowFramebufferWorker(SDL_Surface* surface)
 {
-    SDL_Surface *surface;
-
-    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
-    surface = data->surface;
-    if (!surface) {
-        return SDL_SetError("Couldn't find framebuffer surface for window");
-    }
-
-    /* Send the data to the display */
-
     EM_ASM_INT({
         var w = $0;
         var h = $1;
@@ -156,6 +149,29 @@ int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rec
         SDL2.ctx.putImageData(SDL2.image, 0, 0);
         return 0;
     }, surface->w, surface->h, surface->pixels);
+}
+
+int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects)
+{
+    SDL_Surface *surface;
+
+    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+    surface = data->surface;
+    if (!surface) {
+        return SDL_SetError("Couldn't find framebuffer surface for window");
+    }
+
+    /* Send the data to the display */
+
+    if (emscripten_is_main_runtime_thread()) {
+        Emscripten_UpdateWindowFramebufferWorker(surface);
+    } else {
+        emscripten_sync_run_in_main_runtime_thread(
+            EM_FUNC_SIG_VI,
+            Emscripten_UpdateWindowFramebufferWorker,
+            (uint32_t)surface
+        );
+    }
 
     if (emscripten_has_asyncify() && SDL_GetHintBoolean(SDL_HINT_EMSCRIPTEN_ASYNCIFY, SDL_TRUE)) {
         /* give back control to browser for screen refresh */

+ 40 - 16
Engine/lib/sdl/src/video/emscripten/SDL_emscriptenmouse.c

@@ -24,6 +24,7 @@
 
 #include <emscripten/emscripten.h>
 #include <emscripten/html5.h>
+#include <emscripten/threading.h>
 
 #include "SDL_emscriptenmouse.h"
 #include "SDL_emscriptenvideo.h"
@@ -62,19 +63,10 @@ Emscripten_CreateDefaultCursor()
     return Emscripten_CreateCursorFromString("default", SDL_FALSE);
 }
 
-static SDL_Cursor*
-Emscripten_CreateCursor(SDL_Surface* surface, int hot_x, int hot_y)
+static const char*
+Emscripten_GetCursorUrl(int w, int h, int hot_x, int hot_y, void* pixels)
 {
-    const char *cursor_url = NULL;
-    SDL_Surface *conv_surf;
-
-    conv_surf = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ABGR8888, 0);
-
-    if (!conv_surf) {
-        return NULL;
-    }
-
-    cursor_url = (const char *)EM_ASM_INT({
+    return (const char *)EM_ASM_INT({
         var w = $0;
         var h = $1;
         var hot_x = $2;
@@ -122,7 +114,40 @@ Emscripten_CreateCursor(SDL_Surface* surface, int hot_x, int hot_y)
         stringToUTF8(url, urlBuf, url.length + 1);
 
         return urlBuf;
-    }, surface->w, surface->h, hot_x, hot_y, conv_surf->pixels);
+    }, w, h, hot_x, hot_y, pixels);
+}
+
+static SDL_Cursor*
+Emscripten_CreateCursor(SDL_Surface* surface, int hot_x, int hot_y)
+{
+    const char *cursor_url = NULL;
+    SDL_Surface *conv_surf;
+
+    conv_surf = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ABGR8888, 0);
+
+    if (!conv_surf) {
+        return NULL;
+    }
+
+    if (emscripten_is_main_runtime_thread()) {
+        cursor_url = Emscripten_GetCursorUrl(
+            surface->w,
+            surface->h,
+            hot_x,
+            hot_y,
+            conv_surf->pixels
+        );
+    } else {
+        cursor_url = (const char *)emscripten_sync_run_in_main_runtime_thread(
+            EM_FUNC_SIG_IIIIIII,
+            Emscripten_GetCursorUrl,
+            surface->w,
+            surface->h,
+            hot_x,
+            hot_y,
+            conv_surf->pixels
+        );
+    }
 
     SDL_FreeSurface(conv_surf);
 
@@ -206,16 +231,15 @@ Emscripten_ShowCursor(SDL_Cursor* cursor)
             curdata = (Emscripten_CursorData *) cursor->driverdata;
 
             if(curdata->system_cursor) {
-                EM_ASM_INT({
+                MAIN_THREAD_EM_ASM({
                     if (Module['canvas']) {
                         Module['canvas'].style['cursor'] = UTF8ToString($0);
                     }
-                    return 0;
                 }, curdata->system_cursor);
             }
         }
         else {
-            EM_ASM(
+            MAIN_THREAD_EM_ASM(
                 if (Module['canvas']) {
                     Module['canvas'].style['cursor'] = 'none';
                 }

+ 2 - 2
Engine/lib/sdl/src/video/emscripten/SDL_emscriptenvideo.c

@@ -174,10 +174,10 @@ Emscripten_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect *
     if (rect) {
         rect->x = 0;
         rect->y = 0;
-        rect->w = EM_ASM_INT_V({
+        rect->w = MAIN_THREAD_EM_ASM_INT({
             return window.innerWidth;
         });
-        rect->h = EM_ASM_INT_V({
+        rect->h = MAIN_THREAD_EM_ASM_INT({
             return window.innerHeight;
         });
     }

+ 19 - 5
Engine/lib/sdl/src/video/uikit/SDL_uikitmessagebox.m

@@ -186,8 +186,8 @@ UIKit_ShowMessageBoxAlertView(const SDL_MessageBoxData *messageboxdata, int *but
 #endif /* __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 */
 }
 
-int
-UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
+static void
+UIKit_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int *buttonid, int *returnValue)
 {
     BOOL success = NO;
 
@@ -199,12 +199,26 @@ UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
     }
 
     if (!success) {
-        return SDL_SetError("Could not show message box.");
+        *returnValue = SDL_SetError("Could not show message box.");
+    } else {
+        *returnValue = 0;
     }
-
-    return 0;
 }
 
+int
+UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
+{ @autoreleasepool
+{
+    __block int returnValue = 0;
+
+    if ([NSThread isMainThread]) {
+        UIKit_ShowMessageBoxImpl(messageboxdata, buttonid, &returnValue);
+    } else {
+        dispatch_sync(dispatch_get_main_queue(), ^{ UIKit_ShowMessageBoxImpl(messageboxdata, buttonid, &returnValue); });
+    }
+    return returnValue;
+}}
+
 #endif /* SDL_VIDEO_DRIVER_UIKIT */
 
 /* vi: set ts=4 sw=4 expandtab: */

+ 1 - 1
Engine/lib/sdl/src/video/vita/SDL_vitaframebuffer.c

@@ -31,7 +31,7 @@
 #define ALIGN(x, a)     (((x) + ((a) - 1)) & ~((a) - 1))
 #define DISPLAY_PIXEL_FORMAT SCE_DISPLAY_PIXELFORMAT_A8B8G8R8
 
-void *vita_gpu_alloc(SceKernelMemBlockType type, unsigned int size, SceUID *uid)
+void *vita_gpu_alloc(unsigned int type, unsigned int size, SceUID *uid)
 {
     void *mem;
 

+ 47 - 18
Engine/lib/sdl/src/video/vita/SDL_vitagl_pvr.c

@@ -20,11 +20,12 @@
 */
 #include "../../SDL_internal.h"
 
-#if SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR
+#if SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR && SDL_VIDEO_VITA_PVR_OGL
 #include <stdlib.h>
 #include <string.h>
 #include <psp2/kernel/modulemgr.h>
 #include <gpu_es4/psp2_pvr_hint.h>
+#include <gl4esinit.h>
 
 #include "SDL_error.h"
 #include "SDL_log.h"
@@ -34,6 +35,16 @@
 
 #define MAX_PATH 256 // vita limits are somehow wrong
 
+/* Defaults */
+int FB_WIDTH = 960;
+int FB_HEIGHT = 544;
+
+void getFBSize(int *width, int *height)
+{
+    *width = FB_WIDTH;
+    *height = FB_HEIGHT;
+}
+
 int
 VITA_GL_LoadLibrary(_THIS, const char *path)
 {
@@ -53,6 +64,9 @@ VITA_GL_LoadLibrary(_THIS, const char *path)
         sceKernelLoadStartModule("vs0:sys/external/libfios2.suprx", 0, NULL, 0, NULL, NULL);
         sceKernelLoadStartModule("vs0:sys/external/libc.suprx", 0, NULL, 0, NULL, NULL);
 
+        SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libGL.suprx");
+        sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL);
+
         SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libgpu_es4_ext.suprx");
         sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL);
 
@@ -74,30 +88,45 @@ VITA_GL_LoadLibrary(_THIS, const char *path)
 SDL_GLContext
 VITA_GL_CreateContext(_THIS, SDL_Window * window)
 {
-    return SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
-}
+    char gl_version[3];
+    SDL_GLContext context = NULL;
+    int temp_major = _this->gl_config.major_version;
+    int temp_minor = _this->gl_config.minor_version;
+    int temp_profile = _this->gl_config.profile_mask;
 
-int
-VITA_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
-{
-    if (window && context) {
-        return SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *) window->driverdata)->egl_surface, context);
-    } else {
-        return SDL_EGL_MakeCurrent(_this, NULL, NULL);
+    /* Set version to 2.0 and PROFILE to ES */
+    _this->gl_config.major_version = 2;
+    _this->gl_config.minor_version = 0;
+    _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES;
+
+    context = SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
+
+    if (context != NULL)
+    {
+        FB_WIDTH = window->w;
+        FB_HEIGHT = window->h;
+        set_getprocaddress((void *(*)(const char *))eglGetProcAddress);
+        set_getmainfbsize(getFBSize);
+        SDL_snprintf(gl_version, 3, "%d%d", temp_major, temp_minor);
+        gl4es_setenv("LIBGL_NOTEXRECT", "1", 1); /* Currently broken in driver */
+        gl4es_setenv("LIBGL_GL", gl_version, 1);
+        initialize_gl4es();
     }
+
+    /* Restore gl_config */
+    _this->gl_config.major_version = temp_major;
+    _this->gl_config.minor_version = temp_minor;
+    _this->gl_config.profile_mask = temp_profile;
+
+    return context;
 }
 
-int
-VITA_GL_SwapWindow(_THIS, SDL_Window * window)
+void *
+VITA_GL_GetProcAddress(_THIS, const char *proc)
 {
-    SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
-    if (videodata->ime_active) {
-        sceImeUpdate();
-    }
-    return SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
+    return gl4es_GetProcAddress(proc);
 }
 
-
 #endif /* SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR */
 
 /* vi: set ts=4 sw=4 expandtab: */

+ 4 - 5
Engine/lib/sdl/src/video/vita/SDL_vitagl_pvr_c.h

@@ -19,17 +19,16 @@
   3. This notice may not be removed or altered from any source distribution.
 */
 
-#ifndef SDL_vitagl_c_h_
-#define SDL_vitagl_c_h_
+#ifndef SDL_vitagl_pvr_c_h_
+#define SDL_vitagl_pvr_c_h_
 
 #include "SDL_vitavideo.h"
 
-extern int VITA_GL_MakeCurrent(_THIS,SDL_Window * window, SDL_GLContext context);
-extern int VITA_GL_SwapWindow(_THIS, SDL_Window * window);
 extern SDL_GLContext VITA_GL_CreateContext(_THIS, SDL_Window * window);
 extern int VITA_GL_LoadLibrary(_THIS, const char *path);
+extern void *VITA_GL_GetProcAddress(_THIS, const char *proc);
 
 
-#endif /* SDL_vitagl_c_h_ */
+#endif /* SDL_vitagl_pvr_c_h_ */
 
 /* vi: set ts=4 sw=4 expandtab: */

+ 12 - 12
Engine/lib/sdl/src/video/vita/SDL_vitagl.c → Engine/lib/sdl/src/video/vita/SDL_vitagles.c

@@ -27,7 +27,7 @@
 #include "SDL_error.h"
 #include "SDL_log.h"
 #include "SDL_vitavideo.h"
-#include "SDL_vitagl_c.h"
+#include "SDL_vitagles_c.h"
 
 /*****************************************************************************/
 /* SDL OpenGL/OpenGL ES functions                                            */
@@ -45,7 +45,7 @@
     } while (0)
 
 void 
-VITA_GL_KeyboardCallback(ScePigletPreSwapData *data)
+VITA_GLES_KeyboardCallback(ScePigletPreSwapData *data)
 {
     SceCommonDialogUpdateParam commonDialogParam;
     SDL_zero(commonDialogParam);
@@ -62,20 +62,20 @@ VITA_GL_KeyboardCallback(ScePigletPreSwapData *data)
 }
 
 int
-VITA_GL_LoadLibrary(_THIS, const char *path)
+VITA_GLES_LoadLibrary(_THIS, const char *path)
 {
   pibInit(PIB_SHACCCG | PIB_GET_PROC_ADDR_CORE);
   return 0;
 }
 
 void *
-VITA_GL_GetProcAddress(_THIS, const char *proc)
+VITA_GLES_GetProcAddress(_THIS, const char *proc)
 {
     return eglGetProcAddress(proc);
 }
 
 void
-VITA_GL_UnloadLibrary(_THIS)
+VITA_GLES_UnloadLibrary(_THIS)
 {
     eglTerminate(_this->gl_data->display);
 }
@@ -84,7 +84,7 @@ static EGLint width = 960;
 static EGLint height = 544;
 
 SDL_GLContext
-VITA_GL_CreateContext(_THIS, SDL_Window * window)
+VITA_GLES_CreateContext(_THIS, SDL_Window * window)
 {
 
     SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
@@ -159,13 +159,13 @@ VITA_GL_CreateContext(_THIS, SDL_Window * window)
     _this->gl_data->surface = surface;
 
     preSwapCallback = (PFNEGLPIGLETVITASETPRESWAPCALLBACKSCEPROC) eglGetProcAddress("eglPigletVitaSetPreSwapCallbackSCE");
-    preSwapCallback(VITA_GL_KeyboardCallback);
+    preSwapCallback(VITA_GLES_KeyboardCallback);
 
     return context;
 }
 
 int
-VITA_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
+VITA_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
 {
         if (!eglMakeCurrent(_this->gl_data->display, _this->gl_data->surface,
                           _this->gl_data->surface, _this->gl_data->context))
@@ -176,7 +176,7 @@ VITA_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
 }
 
 int
-VITA_GL_SetSwapInterval(_THIS, int interval)
+VITA_GLES_SetSwapInterval(_THIS, int interval)
 {
     EGLBoolean status;
     status = eglSwapInterval(_this->gl_data->display, interval);
@@ -190,13 +190,13 @@ VITA_GL_SetSwapInterval(_THIS, int interval)
 }
 
 int
-VITA_GL_GetSwapInterval(_THIS)
+VITA_GLES_GetSwapInterval(_THIS)
 {
     return _this->gl_data->swapinterval;
 }
 
 int
-VITA_GL_SwapWindow(_THIS, SDL_Window * window)
+VITA_GLES_SwapWindow(_THIS, SDL_Window * window)
 {
     if (!eglSwapBuffers(_this->gl_data->display, _this->gl_data->surface)) {
         return SDL_SetError("eglSwapBuffers() failed");
@@ -205,7 +205,7 @@ VITA_GL_SwapWindow(_THIS, SDL_Window * window)
 }
 
 void
-VITA_GL_DeleteContext(_THIS, SDL_GLContext context)
+VITA_GLES_DeleteContext(_THIS, SDL_GLContext context)
 {
     SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
     EGLBoolean status;

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