diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..01d4945e7 --- /dev/null +++ b/.clang-format @@ -0,0 +1,86 @@ +--- +AlignConsecutiveMacros: Consecutive +AlignConsecutiveAssignments: None +AlignConsecutiveBitFields: None +AlignConsecutiveDeclarations: None +AlignEscapedNewlines: Right +AlignOperands: Align +AlignTrailingComments: true + +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortEnumsOnASingleLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: AllIfsAndElse +AllowShortLoopsOnASingleLine: false + +AlwaysBreakAfterDefinitionReturnType: All +AlwaysBreakAfterReturnType: AllDefinitions +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine + +# Custom brace breaking +BreakBeforeBraces: Custom +BraceWrapping: + AfterCaseLabel: true + AfterClass: true + AfterControlStatement: Never + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: false + BeforeElse: false + BeforeWhile: true + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + +# Make the closing brace of container literals go to a new line +Cpp11BracedListStyle: false + +# Never format includes +IncludeBlocks: Preserve +SortIncludes: Never + +# No length limit, in case it breaks macros, you can +# disable it with /* clang-format off/on */ comments +ColumnLimit: 0 + +IndentWidth: 4 +ContinuationIndentWidth: 4 +IndentCaseLabels: false +IndentCaseBlocks: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentExternBlock: NoIndent + +SpaceAfterCStyleCast: true +SpacesInCStyleCastParentheses: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeParens: ControlStatements +SpaceAroundPointerQualifiers: Default +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false + +UseCRLF: false +UseTab: Never + +ForEachMacros: + [ + "spa_list_for_each", + "spa_list_for_each_safe", + "wl_list_for_each", + "wl_array_for_each", + "udev_list_entry_foreach", + ] + +--- + diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..1c6df767a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,77 @@ +# For format see editorconfig.org +# Copyright 2022 Collabora Ltd. +# SPDX-License-Identifier: Zlib + +root = true + +[*.{c,cg,cpp,gradle,h,java,m,metal,pl,py,S,sh,txt}] +indent_size = 4 +indent_style = space + +[*.{html,js,json,m4,yml,yaml,vcxproj,vcxproj.filters}] +indent_size = 2 +indent_style = space + +[*.xml] +indent_size = 4 +indent_style = space + +[{CMakeLists.txt,sdl2-config*.cmake.in,cmake/*.cmake}] +indent_size = 2 +indent_style = space + +[{cmake_uninstall.cmake.in,test/CMakeLists.txt}] +indent_size = 4 +indent_style = space + +[configure.ac] +# Inconsistently 2-, 4- or occasionally 3-space indented, but mostly 4, +# so let's use 4 for new code +indent_size = 4 +indent_style = space + +[{Makefile.*,*.mk,*.sln,*.pbxproj,*.plist}] +indent_size = 8 +indent_style = tab +tab_width = 8 + +[Makefile.os2] +indent_size = 4 +indent_style = space + +[test/Makefile.os2] +indent_size = 2 +indent_style = space + +[{src/core/os2/geniconv/makefile,src/core/os2/geniconv/os2cp.c}] +indent_size = 2 +indent_style = space + +[src/joystick/controller_type.h] +indent_style = tab + +[src/joystick/hidapi/steam/*.h] +indent_style = tab + +[src/libm/*.c] +indent_style = tab + +[src/test/SDL_test_{crc32,md5,random}.c] +indent_size = 2 +indent_style = space + +[src/video/yuv2rgb/*.{c,h}] +indent_style = tab + +[src/wayland-protocols/*.xml] +indent_size = 2 +indent_style = space + +[*.{markdown,md}] +indent_size = 4 +indent_style = space +# Markdown syntax treats tabs as 4 spaces +tab_width = 4 + +[{*.bat,*.rc}] +end_of_line = crlf diff --git a/.github/workflows/emscripten.yml b/.github/workflows/emscripten.yml index 633c39125..04372bf47 100644 --- a/.github/workflows/emscripten.yml +++ b/.github/workflows/emscripten.yml @@ -11,6 +11,6 @@ jobs: with: version: 2.0.27 - name: Configure CMake - run: emcmake cmake -B build + run: emcmake cmake -B build -DCMAKE_VERBOSE_MAKEFILE=ON - name: Build run: cmake --build build/ diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 098c6a713..9f8d83d2f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,7 +17,8 @@ jobs: platform: - { name: Windows (mingw32), os: windows-latest, shell: 'msys2 {0}', msystem: mingw32, msys-env: mingw-w64-i686 } - { name: Windows (mingw64), os: windows-latest, shell: 'msys2 {0}', msystem: mingw64, msys-env: mingw-w64-x86_64 } - - { name: Linux, os: ubuntu-20.04, shell: sh, flags: -GNinja } + - { name: Linux (CMake), os: ubuntu-20.04, shell: sh, flags: -GNinja } + - { name: Linux (autotools), os: ubuntu-20.04, shell: sh, autotools: 'true' } - { name: MacOS, os: macos-latest, shell: sh } steps: @@ -36,7 +37,10 @@ jobs: if: runner.os == 'Linux' run: | sudo apt-get update - sudo apt-get install wayland-protocols \ + sudo apt-get install \ + autoconf \ + gnome-desktop-testing \ + wayland-protocols \ pkg-config \ ninja-build \ libasound2-dev \ @@ -73,11 +77,105 @@ jobs: git clone --depth 1 https://gitlab.gnome.org/jadahl/libdecor.git --branch 0.1.0 cd libdecor meson build --buildtype release -Ddemo=false -Ddbus=disabled - ninja -C build + ninja -v -C build sudo meson install -C build - uses: actions/checkout@v2 + - name: Check that versioning is consistent + # We only need to run this once: arbitrarily use the Linux/CMake build + if: "runner.os == 'Linux' && ! matrix.platform.autotools" + run: ./test/versioning.sh - name: Configure CMake - run: cmake -B build -DSDL_TEST=ON ${{ matrix.platform.flags }} + if: "! matrix.platform.autotools" + run: cmake -B build -DSDL_TEST=ON -DCMAKE_VERBOSE_MAKEFILE=ON -DSDL_INSTALL_TESTS=ON ${{ matrix.platform.flags }} - name: Build + if: "! matrix.platform.autotools" run: cmake --build build/ --config Release - + - name: Run build-time tests + if: "matrix.platform.shell == 'sh' && ! matrix.platform.autotools" + run: | + set -eu + export SDL_TESTS_QUICK=1 + ctest -VV --test-dir build/ + - name: Install + if: "matrix.platform.shell == 'sh' && ! matrix.platform.autotools" + run: | + set -eu + rm -fr DESTDIR-cmake + DESTDIR=$(pwd)/DESTDIR-cmake cmake --install build/ --config Release + ( cd DESTDIR-cmake; find ) | LC_ALL=C sort -u + - name: Configure Autotools + if: matrix.platform.autotools + run: | + set -eu + rm -fr build-autotools + mkdir build-autotools + ./autogen.sh + ( cd build-autotools && ../configure ) + curdir="$(pwd)" + multiarch="$(dpkg-architecture -qDEB_HOST_MULTIARCH)" + ( + mkdir -p build-autotools/test + cd build-autotools/test + ../../test/configure \ + --x-includes=/usr/include \ + --x-libraries="/usr/lib/${multiarch}" \ + SDL_CFLAGS="-I${curdir}/include" \ + SDL_LIBS="-L${curdir}/build-autotools/build/.libs -lSDL2" \ + ac_cv_lib_SDL2_ttf_TTF_Init=no \ + ${NULL+} + ) + - name: Build with Autotools + if: matrix.platform.autotools + run: | + set -eu + parallel="$(getconf _NPROCESSORS_ONLN)" + make -j"${parallel}" -C build-autotools V=1 + make -j"${parallel}" -C build-autotools/test V=1 + - name: Run build-time tests with Autotools + if: matrix.platform.autotools + run: | + set -eu + curdir="$(pwd)" + parallel="$(getconf _NPROCESSORS_ONLN)" + export SDL_TESTS_QUICK=1 + make -j"${parallel}" -C build-autotools/test check LD_LIBRARY_PATH="${curdir}/build-autotools/build/.libs" + - name: Install with Autotools + if: matrix.platform.autotools + run: | + set -eu + curdir="$(pwd)" + parallel="$(getconf _NPROCESSORS_ONLN)" + rm -fr DESTDIR-autotools + mkdir DESTDIR-autotools + make -j"${parallel}" -C build-autotools install DESTDIR="${curdir}/DESTDIR-autotools" V=1 + make -j"${parallel}" -C build-autotools/test install DESTDIR="${curdir}/DESTDIR-autotools" V=1 + ( cd DESTDIR-autotools; find ) | LC_ALL=C sort -u + - name: Distcheck + if: matrix.platform.autotools + run: | + set -eu + parallel="$(getconf _NPROCESSORS_ONLN)" + make -j"${parallel}" -C build-autotools dist V=1 + # Similar to Automake `make distcheck`: check that the tarball + # release is sufficient to do a new build + mkdir distcheck + tar -C distcheck -zxf build-autotools/SDL2-*.tar.gz + ( cd distcheck/SDL2-* && ./configure ) + make -j"${parallel}" -C distcheck/SDL2-* + - name: Run installed-tests from Autotools + if: "runner.os == 'Linux' && matrix.platform.autotools" + run: | + set -eu + parallel="$(getconf _NPROCESSORS_ONLN)" + sudo make -j"${parallel}" -C build-autotools install + sudo make -j"${parallel}" -C build-autotools/test install + export SDL_TESTS_QUICK=1 + # We need to set LD_LIBRARY_PATH because it isn't in the default + # linker search path. We don't need to set XDG_DATA_DIRS for + # ginsttest-runner, because /usr/local/share *is* in the default + # search path for that. + env --chdir=/ \ + LD_LIBRARY_PATH=/usr/local/lib \ + SDL_AUDIODRIVER=dummy \ + SDL_VIDEODRIVER=dummy \ + ginsttest-runner --tap SDL2 diff --git a/.github/workflows/msvc.yml b/.github/workflows/msvc.yml index ca78cb1c7..39e23e4c0 100644 --- a/.github/workflows/msvc.yml +++ b/.github/workflows/msvc.yml @@ -13,8 +13,11 @@ jobs: platform: - { name: Windows (x64), flags: -A x64, project: VisualC/SDL.sln, projectflags: '/p:Platform=x64' } - { name: Windows (x86), flags: -A Win32, project: VisualC/SDL.sln, projectflags: '/p:Platform=Win32' } + - { name: Windows static VCRT (x64), flags: -A x64 -DSDL_FORCE_STATIC_VCRT=ON } + - { name: Windows static VCRT (x86), flags: -A Win32 -DSDL_FORCE_STATIC_VCRT=ON } - { name: Windows (clang-cl x64), flags: -T ClangCL -A x64 } - { name: Windows (clang-cl x86), flags: -T ClangCL -A Win32 } + - { name: Windows (ARM), flags: -A ARM } - { name: Windows (ARM64), flags: -A ARM64 } - { name: UWP (x64), flags: -A x64 -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION="10.0" -DSDL_TEST=OFF, project: VisualC-WinRT/SDL-UWP.sln, projectflags: '/p:Platform=x64 /p:WindowsTargetPlatformVersion=10.0.17763.0' } diff --git a/.github/workflows/os2.yml b/.github/workflows/os2.yml deleted file mode 100644 index 2ae10643b..000000000 --- a/.github/workflows/os2.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Build (OS/2) - -on: [push, pull_request] - -jobs: - os2: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: open-watcom/setup-watcom@v0 - - name: Build SDL2 - run: | - wmake -f Makefile.os2 - - name: Build tests - run: | - cd test && wmake -f Makefile.os2 - cd .. - - name: distclean - run: | - wmake -f Makefile.os2 distclean - cd test && wmake -f Makefile.os2 distclean - cd .. diff --git a/.github/workflows/riscos.yml b/.github/workflows/riscos.yml index 3f46668b7..9f3370567 100644 --- a/.github/workflows/riscos.yml +++ b/.github/workflows/riscos.yml @@ -12,7 +12,7 @@ jobs: - name: Configure run: ./configure --host=arm-unknown-riscos --disable-gcc-atomics - name: Build - run: make -j`nproc` + run: make -j`nproc` V=1 cmake: name: CMake @@ -23,6 +23,6 @@ jobs: run: apt-get update && apt-get install -y cmake ninja-build - uses: actions/checkout@v2 - name: Configure CMake - run: cmake -S. -Bbuild -G Ninja -DCMAKE_TOOLCHAIN_FILE=/home/riscos/env/toolchain-riscos.cmake -DRISCOS=ON -DSDL_GCC_ATOMICS=OFF -DCMAKE_BUILD_TYPE=Release + run: cmake -S. -Bbuild -G Ninja -DCMAKE_TOOLCHAIN_FILE=/home/riscos/env/toolchain-riscos.cmake -DRISCOS=ON -DSDL_GCC_ATOMICS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_VERBOSE_MAKEFILE=ON - name: Build run: cmake --build build diff --git a/.github/workflows/watcom.yml b/.github/workflows/watcom.yml new file mode 100644 index 000000000..ead7c4724 --- /dev/null +++ b/.github/workflows/watcom.yml @@ -0,0 +1,35 @@ +name: Build (OpenWatcom) + +on: [push, pull_request] + +jobs: + os2: + name: ${{ matrix.platform.name }} + runs-on: windows-latest + + strategy: + matrix: + platform: + - { name: Windows, makefile: Makefile.w32 } + - { name: OS/2, makefile: Makefile.os2 } + + steps: + - uses: actions/checkout@v2 + - uses: open-watcom/setup-watcom@v0 + - name: Build SDL2 + run: | + wmake -f ${{ matrix.platform.makefile }} + - name: Build tests + run: | + cd test && wmake -f ${{ matrix.platform.makefile }} + cd .. + - name: Run tests + if: "matrix.platform.makefile == 'Makefile.w32'" + run: | + cd test && wmake -f ${{ matrix.platform.makefile }} check-quick + cd .. + - name: distclean + run: | + wmake -f ${{ matrix.platform.makefile }} distclean + cd test && wmake -f ${{ matrix.platform.makefile }} distclean + cd .. diff --git a/.gitignore b/.gitignore index fd27cb76a..1f5e7249f 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ buildbot *.exe *.o *.obj +*.res *.lib *.a *.la diff --git a/CMakeLists.txt b/CMakeLists.txt index 3828cb949..437e1d83b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,23 +56,11 @@ set(CMAKE_MODULE_PATH "${SDL2_SOURCE_DIR}/cmake") include(${SDL2_SOURCE_DIR}/cmake/macros.cmake) include(${SDL2_SOURCE_DIR}/cmake/sdlchecks.cmake) -# General settings -# Edit include/SDL_version.h and change the version, then: -# SDL_MICRO_VERSION += 1; -# SDL_INTERFACE_AGE += 1; -# SDL_BINARY_AGE += 1; -# if any functions have been added, set SDL_INTERFACE_AGE to 0. -# if backwards compatibility has been broken, -# set SDL_BINARY_AGE and SDL_INTERFACE_AGE to 0. +# See docs/release_checklist.md set(SDL_MAJOR_VERSION 2) -set(SDL_MINOR_VERSION 0) -set(SDL_MICRO_VERSION 22) -set(SDL_INTERFACE_AGE 0) -set(SDL_BINARY_AGE 22) +set(SDL_MINOR_VERSION 23) +set(SDL_MICRO_VERSION 0) 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 23.0.0) -set(DYLIB_COMPATIBILITY_VERSION 1.0.0) # Set defaults preventing destination file conflicts set(SDL_CMAKE_DEBUG_POSTFIX "d" @@ -81,13 +69,40 @@ set(SDL_CMAKE_DEBUG_POSTFIX "d" mark_as_advanced(CMAKE_IMPORT_LIBRARY_SUFFIX SDL_CMAKE_DEBUG_POSTFIX) # Calculate a libtool-like version number -math(EXPR LT_CURRENT "${SDL_MICRO_VERSION} - ${SDL_INTERFACE_AGE}") +math(EXPR SDL_BINARY_AGE "${SDL_MINOR_VERSION} * 100 + ${SDL_MICRO_VERSION}") +if(SDL_MINOR_VERSION MATCHES "[02468]$") + # Stable branch, 2.24.1 -> libSDL2-2.0.so.0.2400.1 + set(SDL_INTERFACE_AGE ${SDL_MICRO_VERSION}) +else() + # Development branch, 2.23.1 -> libSDL2-2.0.so.0.2301.0 + set(SDL_INTERFACE_AGE 0) +endif() + +# Increment this if there is an incompatible change - but if that happens, +# we should rename the library from SDL2 to SDL3, at which point this would +# reset to 0 anyway. +set(LT_MAJOR "0") + math(EXPR LT_AGE "${SDL_BINARY_AGE} - ${SDL_INTERFACE_AGE}") -math(EXPR LT_MAJOR "${LT_CURRENT}- ${LT_AGE}") +math(EXPR LT_CURRENT "${LT_MAJOR} + ${LT_AGE}") set(LT_REVISION "${SDL_INTERFACE_AGE}") -set(LT_RELEASE "${SDL_MAJOR_VERSION}.${SDL_MINOR_VERSION}") +# For historical reasons, the library name redundantly includes the major +# version twice: libSDL2-2.0.so.0. +# TODO: in SDL 3, set the OUTPUT_NAME to plain SDL3, which will simplify +# it to libSDL3.so.0 +set(LT_RELEASE "2.0") set(LT_VERSION "${LT_MAJOR}.${LT_AGE}.${LT_REVISION}") +# The following should match the versions in the Xcode project file. +# Each version is 1 higher than you might expect, for compatibility +# with libtool: macOS ABI versioning is 1-based, unlike other platforms +# which are normally 0-based. +math(EXPR DYLIB_CURRENT_VERSION_MAJOR "${LT_MAJOR} + ${LT_AGE} + 1") +math(EXPR DYLIB_CURRENT_VERSION_MINOR "${LT_REVISION}") +math(EXPR DYLIB_COMPAT_VERSION_MAJOR "${LT_MAJOR} + 1") +set(DYLIB_CURRENT_VERSION "${DYLIB_CURRENT_VERSION_MAJOR}.${DYLIB_CURRENT_VERSION_MINOR}.0") +set(DYLIB_COMPATIBILITY_VERSION "${DYLIB_COMPAT_VERSION_MAJOR}.0.0") + #message(STATUS "${LT_VERSION} :: ${LT_AGE} :: ${LT_REVISION} :: ${LT_CURRENT} :: ${LT_RELEASE}") # General settings & flags @@ -423,7 +438,7 @@ set_option(SDL_RPATH "Use an rpath when linking SDL" ${UNIX_SYS}) set_option(SDL_CLOCK_GETTIME "Use clock_gettime() instead of gettimeofday()" ${UNIX_SYS}) set_option(SDL_X11 "Use X11 video driver" ${UNIX_SYS}) dep_option(SDL_X11_SHARED "Dynamically load X11 support" ON "SDL_X11" OFF) -set(SDL_X11_OPTIONS Xcursor Xdbe Xinerama XInput Xfixes Xrandr Xscrnsaver XShape Xvm) +set(SDL_X11_OPTIONS Xcursor Xdbe XInput Xfixes Xrandr Xscrnsaver XShape) foreach(_SUB ${SDL_X11_OPTIONS}) string(TOUPPER "SDL_X11_${_SUB}" _OPT) dep_option(${_OPT} "Enable ${_SUB} support" ON "SDL_X11" OFF) @@ -457,6 +472,7 @@ set(SDL_STATIC ${SDL_STATIC_ENABLED_BY_DEFAULT} CACHE BOOL "Build a static versi dep_option(SDL_STATIC_PIC "Static version of the library should be built with Position Independent Code" OFF "SDL_STATIC" OFF) set_option(SDL_TEST "Build the test directory" OFF) +set_option(SDL_INSTALL_TESTS "Install test-cases" OFF) if(VITA) set_option(VIDEO_VITA_PIB "Build with PSVita piglet gles2 support" OFF) @@ -611,10 +627,14 @@ if(USE_GCC OR USE_CLANG) endif() endif() endif() +if(MSVC) + target_compile_definitions(sdl-build-options INTERFACE "-D_CRT_SECURE_NO_DEPRECATE") + target_compile_definitions(sdl-build-options INTERFACE "-D_CRT_NONSTDC_NO_DEPRECATE") + target_compile_definitions(sdl-build-options INTERFACE "-D_CRT_SECURE_NO_WARNINGS") +endif() if(SDL_ASSEMBLY) if(USE_GCC OR USE_CLANG) - set(SDL_ASSEMBLY_ROUTINES 1) # TODO: Those all seem to be quite GCC specific - needs to be # reworked for better compiler support set(HAVE_ASSEMBLY TRUE) @@ -832,7 +852,6 @@ if(SDL_ASSEMBLY) set(HAVE_SSE2 TRUE) set(HAVE_SSE3 TRUE) check_include_file("immintrin.h" HAVE_IMMINTRIN_H) - set(SDL_ASSEMBLY_ROUTINES 1) endif() endif() @@ -848,7 +867,7 @@ if(SDL_LIBC) endforeach() set(HAVE_SIGNAL_H 1) foreach(_FN - malloc calloc realloc free qsort abs memset memcpy memmove memcmp + malloc calloc realloc free bsearch qsort abs memset memcpy memmove memcmp wcslen _wcsdup wcsdup wcsstr wcscmp wcsncmp _wcsicmp _wcsnicmp strlen _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _ultoa strtol strtoul strtoll strtod atoi atof strcmp strncmp @@ -885,7 +904,7 @@ if(SDL_LIBC) int main(void) { return 0; }" HAVE_MPROTECT) foreach(_FN strtod malloc calloc realloc free getenv setenv putenv unsetenv - qsort abs bcopy memset memcpy memmove memcmp strlen strlcpy strlcat + bsearch qsort abs bcopy memset memcpy memmove memcmp strlen strlcpy strlcat _strrev _strupr _strlwr index rindex strchr strrchr strstr strtok_r itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp @@ -1529,7 +1548,7 @@ elseif(WINDOWS) if(MSVC AND NOT SDL_LIBC) # Prevent codegen that would use the VC runtime libraries. set_property(DIRECTORY . APPEND PROPERTY COMPILE_OPTIONS "/GS-") - if(NOT ARCH_64) + if(NOT ARCH_64 AND NOT CMAKE_GENERATOR_PLATFORM STREQUAL "ARM") set_property(DIRECTORY . APPEND PROPERTY COMPILE_OPTIONS "/arch:SSE") endif() endif() @@ -1561,7 +1580,7 @@ elseif(WINDOWS) check_include_file(ddraw.h HAVE_DDRAW_H) check_include_file(dsound.h HAVE_DSOUND_H) check_include_file(dinput.h HAVE_DINPUT_H) - if(WINDOWS_STORE OR VCPKG_TARGET_TRIPLET MATCHES "arm-windows") + if(WINDOWS_STORE OR CMAKE_GENERATOR_PLATFORM STREQUAL "ARM") set(HAVE_DINPUT_H 0) endif() check_include_file(dxgi.h HAVE_DXGI_H) @@ -2920,6 +2939,9 @@ if(NOT WINDOWS_STORE AND NOT SDL2_DISABLE_SDL2MAIN) add_library(SDL2::SDL2main ALIAS SDL2main) target_include_directories(SDL2main BEFORE PRIVATE "${SDL2_BINARY_DIR}/include") target_include_directories(SDL2main PUBLIC "$" $ $) + if (WIN32) + target_link_libraries(SDL2main PRIVATE shell32) + endif() if (NOT ANDROID) set_target_properties(SDL2main PROPERTIES DEBUG_POSTFIX "${SDL_CMAKE_DEBUG_POSTFIX}") endif() @@ -2929,7 +2951,7 @@ if(ANDROID) target_include_directories(sdl-build-options INTERFACE "${ANDROID_NDK}/sources/android/cpufeatures") endif() -if(IOS OR TVOS) +if(APPLE) target_compile_options(sdl-build-options INTERFACE "-fobjc-arc") endif() @@ -2960,7 +2982,7 @@ if(SDL_SHARED) OUTPUT_NAME "SDL2") endif() # Note: The clang toolset for Visual Studio does not support /NODEFAULTLIB. - if(MSVC AND NOT SDL_LIBC AND NOT MSVC_CLANG) + if(MSVC AND NOT SDL_LIBC AND NOT MSVC_CLANG AND NOT CMAKE_GENERATOR_PLATFORM STREQUAL "ARM") # Don't try to link with the default set of libraries. if(NOT WINDOWS_STORE) set_target_properties(SDL2 PROPERTIES LINK_FLAGS_RELEASE "/NODEFAULTLIB") @@ -2992,7 +3014,7 @@ if(SDL_STATIC) endif() set_target_properties(SDL2-static PROPERTIES POSITION_INDEPENDENT_CODE ${SDL_STATIC_PIC}) # Note: The clang toolset for Visual Studio does not support /NODEFAULTLIB. - if(MSVC AND NOT SDL_LIBC AND NOT MSVC_CLANG) + if(MSVC AND NOT SDL_LIBC AND NOT MSVC_CLANG AND NOT CMAKE_GENERATOR_PLATFORM STREQUAL "ARM") set_target_properties(SDL2-static PROPERTIES LINK_FLAGS_RELEASE "/NODEFAULTLIB") set_target_properties(SDL2-static PROPERTIES LINK_FLAGS_DEBUG "/NODEFAULTLIB") set_target_properties(SDL2-static PROPERTIES STATIC_LIBRARY_FLAGS "/NODEFAULTLIB") @@ -3009,14 +3031,18 @@ if(SDL_STATIC) endif() endif() +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSDL_BUILD_MAJOR_VERSION=${SDL_MAJOR_VERSION}") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSDL_BUILD_MINOR_VERSION=${SDL_MINOR_VERSION}") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSDL_BUILD_MICRO_VERSION=${SDL_MICRO_VERSION}") + ##### Tests ##### if(SDL_TEST) + include(CTest) include_directories(BEFORE "${SDL2_BINARY_DIR}/include") include_directories(AFTER "${SDL2_SOURCE_DIR}/include") file(GLOB TEST_SOURCES ${SDL2_SOURCE_DIR}/src/test/*.c) add_library(SDL2_test STATIC ${TEST_SOURCES}) - add_subdirectory(test) endif() ##### Installation targets ##### @@ -3142,3 +3168,8 @@ if(NOT SDL2_DISABLE_UNINSTALL) endif() endif() +##### Tests subproject (must appear after the install/uninstall targets) ##### + +if(SDL_TEST) + add_subdirectory(test) +endif() diff --git a/Makefile.os2 b/Makefile.os2 index cfd0d6562..40ba0e8fc 100644 --- a/Makefile.os2 +++ b/Makefile.os2 @@ -11,7 +11,10 @@ # wmake -f Makefile.os2 HIDAPI=1 LIBNAME = SDL2 -VERSION = 2.0.22 +MAJOR_VERSION = 2 +MINOR_VERSION = 23 +MICRO_VERSION = 0 +VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION) DESCRIPTION = Simple DirectMedia Layer 2 LIBICONV=0 @@ -60,6 +63,10 @@ CFLAGS_DLL+= -DHAVE_LIBUSB_H=1 # building SDL itself (for DECLSPEC): CFLAGS_DLL+= -DBUILD_SDL +CFLAGS_DLL+= -DSDL_BUILD_MAJOR_VERSION=$(MAJOR_VERSION) +CFLAGS_DLL+= -DSDL_BUILD_MINOR_VERSION=$(MINOR_VERSION) +CFLAGS_DLL+= -DSDL_BUILD_MICRO_VERSION=$(MICRO_VERSION) + 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 diff --git a/Makefile.w32 b/Makefile.w32 new file mode 100644 index 000000000..48f4e2bcc --- /dev/null +++ b/Makefile.w32 @@ -0,0 +1,222 @@ +# Open Watcom makefile to build SDL2.dll for Win32 +# wmake -f Makefile.w32 + +LIBNAME = SDL2 +MAJOR_VERSION = 2 +MINOR_VERSION = 23 +MICRO_VERSION = 0 +VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION) +DESCRIPTION = Simple DirectMedia Layer 2 + +LIBHOME = . +DLLFILE = $(LIBHOME)/$(LIBNAME).dll +LIBFILE = $(LIBHOME)/$(LIBNAME).lib +EXPFILE = $(LIBHOME)/$(LIBNAME).exp +LNKFILE = $(LIBNAME).lnk + +INCPATH = -I"$(%WATCOM)/h/nt" -I"$(%WATCOM)/h/nt/directx" -I"$(%WATCOM)/h" +INCPATH+= -Iinclude +INCPATH+= -I"src/video/khronos" + +TLIB = SDL2test.lib +LIBS = user32.lib gdi32.lib winmm.lib imm32.lib ole32.lib oleaut32.lib shell32.lib setupapi.lib version.lib uuid.lib dxguid.lib + +CFLAGS = -bt=nt -d0 -q -bm -5s -fp5 -fpi87 -sg -oeatxhn -ei +# max warnings: +CFLAGS+= -wx +# newer OpenWatcom versions enable W303 by default +CFLAGS+= -wcd=303 +# the include paths : +CFLAGS+= $(INCPATH) +CFLAGS_STATIC=$(CFLAGS) +# building dll: +CFLAGS_DLL =$(CFLAGS) +CFLAGS_DLL+= -bd +# we override the DECLSPEC define in begin_code.h, because we are using +# an exports file to remove the _cdecl '_' prefix from the symbol names +CFLAGS_DLL+= -DDECLSPEC= + +CFLAGS_DLL+= -DSDL_BUILD_MAJOR_VERSION=$(MAJOR_VERSION) +CFLAGS_DLL+= -DSDL_BUILD_MINOR_VERSION=$(MINOR_VERSION) +CFLAGS_DLL+= -DSDL_BUILD_MICRO_VERSION=$(MICRO_VERSION) + +RCFLAGS = -q -r -bt=nt $(INCPATH) + +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 +SRCS+= SDL_audio.c SDL_audiocvt.c SDL_audiodev.c SDL_audiotypecvt.c SDL_mixer.c SDL_wave.c +SRCS+= SDL_events.c SDL_quit.c SDL_keyboard.c SDL_mouse.c SDL_windowevents.c & + SDL_clipboardevents.c SDL_dropevents.c SDL_displayevents.c SDL_gesture.c & + SDL_sensor.c SDL_touch.c +SRCS+= SDL_haptic.c SDL_hidapi.c SDL_gamecontroller.c SDL_joystick.c +SRCS+= SDL_render.c yuv_rgb.c SDL_yuv.c SDL_yuv_sw.c SDL_blendfillrect.c & + SDL_blendline.c SDL_blendpoint.c SDL_drawline.c SDL_drawpoint.c & + SDL_render_sw.c SDL_rotate.c SDL_triangle.c +SRCS+= SDL_blit.c SDL_blit_0.c SDL_blit_1.c SDL_blit_A.c SDL_blit_auto.c & + SDL_blit_copy.c SDL_blit_N.c SDL_blit_slow.c SDL_fillrect.c SDL_bmp.c & + SDL_pixels.c SDL_rect.c SDL_RLEaccel.c SDL_shape.c SDL_stretch.c & + SDL_surface.c SDL_video.c SDL_clipboard.c SDL_vulkan_utils.c SDL_egl.c + +SRCS+= e_atan2.c e_exp.c e_fmod.c e_log10.c e_log.c e_pow.c e_rem_pio2.c e_sqrt.c & + k_cos.c k_rem_pio2.c k_sin.c k_tan.c & + s_atan.c s_copysign.c s_cos.c s_fabs.c s_floor.c s_scalbn.c s_sin.c s_tan.c + +SRCS+= SDL_syscond.c SDL_sysmutex.c SDL_syssem.c SDL_systhread.c SDL_systls.c +SRCS+= SDL_systimer.c +SRCS+= SDL_sysloadso.c +SRCS+= SDL_sysfilesystem.c +SRCS+= SDL_syshaptic.c SDL_sysjoystick.c SDL_virtualjoystick.c +SRCS+= SDL_hidapijoystick.c SDL_hidapi_rumble.c SDL_hidapi_gamecube.c SDL_hidapi_luna.c SDL_hidapi_ps4.c SDL_hidapi_ps5.c SDL_hidapi_stadia.c SDL_hidapi_switch.c SDL_hidapi_xbox360.c SDL_hidapi_xbox360w.c SDL_hidapi_xboxone.c SDL_hidapi_steam.c +SRCS+= SDL_dummyaudio.c SDL_diskaudio.c +SRCS+= SDL_nullvideo.c SDL_nullframebuffer.c SDL_nullevents.c +SRCS+= SDL_dummysensor.c +SRCS+= SDL_locale.c SDL_syslocale.c +SRCS+= SDL_url.c SDL_sysurl.c + +SRCS+= SDL_winmm.c SDL_directsound.c SDL_wasapi.c SDL_wasapi_win32.c +SRCS+= SDL_hid.c SDL_windows.c SDL_xinput.c +SRCS+= SDL_dinputhaptic.c SDL_windowshaptic.c SDL_xinputhaptic.c +SRCS+= SDL_dinputjoystick.c SDL_rawinputjoystick.c SDL_windowsjoystick.c SDL_windows_gaming_input.c SDL_xinputjoystick.c +SRCS+= SDL_syspower.c +SRCS+= SDL_d3dmath.c +SRCS+= SDL_render_d3d.c SDL_shaders_d3d.c +SRCS+= SDL_render_d3d11.c SDL_shaders_d3d11.c +SRCS+= SDL_render_gl.c SDL_shaders_gl.c +SRCS+= SDL_render_gles2.c SDL_shaders_gles2.c +SRCS+= SDL_windowssensor.c +SRCS+= SDL_syscond_cv.c +SRCS+= SDL_windowsclipboard.c SDL_windowsevents.c SDL_windowsframebuffer.c SDL_windowskeyboard.c SDL_windowsmessagebox.c SDL_windowsmodes.c SDL_windowsmouse.c SDL_windowsopengl.c SDL_windowsopengles.c SDL_windowsshape.c SDL_windowsvideo.c SDL_windowsvulkan.c SDL_windowswindow.c + +SRCS+= SDL_dynapi.c + +RCSRCS+= version.rc + +OBJS = $(SRCS:.c=.obj) +RCOBJS= $(RCSRCS:.rc=.res) + +.extensions: +.extensions: .lib .dll .obj .res .c .rc .asm + +.c: ./src/libm; +.c: ./src;./src/dynapi;./src/audio;./src/cpuinfo;./src/events;./src/file;./src/haptic;./src/joystick;./src/power;./src/render;./src/render/software;./src/sensor;./src/stdlib;./src/thread;./src/timer;./src/video;./src/video/yuv2rgb;./src/atomic;./src/audio/disk; +.c: ./src/haptic/dummy;./src/joystick/dummy;./src/joystick/virtual;./src/audio/dummy;./src/video/dummy;./src/sensor/dummy; +.c: ./src/core/windows;./src/audio/winmm;./src/audio/directsound;./src/audio/wasapi;./src/loadso/windows;./src/filesystem/windows;./src/haptic/windows;./src/joystick/windows;./src/sensor/windows;./src/thread/windows;./src/timer/windows;./src/video/windows; +.c: ./src/locale/;./src/locale/windows;./src/misc;./src/misc/windows;./src/power/windows;./src/joystick/hidapi;./src/hidapi;./src/render/direct3d;./src/render/direct3d11;./src/render/opengl;./src/render/opengles2 +.rc: ./src/main/windows + +all: $(DLLFILE) $(LIBFILE) $(TLIB) .symbolic + +build_dll: .symbolic + @echo * Compiling dll objects + +$(DLLFILE): build_dll $(OBJS) $(MOBJS) $(RCOBJS) $(LNKFILE) + @echo * Linking: $@ + wlink @$(LNKFILE) + wrc $(RCOBJS) $^@ + +$(LIBFILE): $(DLLFILE) + @echo * Creating LIB file: $@ + wlib -q -b -n -c -pa -s -t -zld -ii -io $* @$(EXPFILE) + +.c.obj: + wcc386 $(CFLAGS_DLL) -fo=$^@ $< + +.rc.res: + wrc $(RCFLAGS) -fo=$^@ $< + +SDL_syscond.obj: "src/thread/generic/SDL_syscond.c" + wcc386 $(CFLAGS_DLL) -fo=$^@ $< +SDL_cpuinfo.obj: SDL_cpuinfo.c + wcc386 $(CFLAGS_DLL) -wcd=200 -fo=$^@ $< +SDL_wave.obj: SDL_wave.c + wcc386 $(CFLAGS_DLL) -wcd=124 -fo=$^@ $< +SDL_blendfillrect.obj: SDL_blendfillrect.c + wcc386 $(CFLAGS_DLL) -wcd=200 -fo=$^@ $< +SDL_blendline.obj: SDL_blendline.c + wcc386 $(CFLAGS_DLL) -wcd=200 -fo=$^@ $< +SDL_blendpoint.obj: SDL_blendpoint.c + wcc386 $(CFLAGS_DLL) -wcd=200 -fo=$^@ $< +SDL_RLEaccel.obj: SDL_RLEaccel.c + wcc386 $(CFLAGS_DLL) -wcd=201 -fo=$^@ $< +# c99 mode needed because of structs with flexible array members in libusb.h +SDL_hidapi.obj: SDL_hidapi.c + wcc386 $(CFLAGS_DLL) -za99 -fo=$^@ $< + +# SDL2test +TSRCS = SDL_test_assert.c SDL_test_common.c SDL_test_compare.c & + SDL_test_crc32.c SDL_test_font.c SDL_test_fuzzer.c SDL_test_harness.c & + SDL_test_imageBlit.c SDL_test_imageBlitBlend.c SDL_test_imageFace.c & + SDL_test_imagePrimitives.c SDL_test_imagePrimitivesBlend.c & + SDL_test_log.c SDL_test_md5.c SDL_test_random.c SDL_test_memory.c +TOBJS= $(TSRCS:.c=.obj) + +.c: ./src/test; +SDL_test_assert.obj: SDL_test_assert.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_common.obj: SDL_test_common.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_compare.obj: SDL_test_compare.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_crc32.obj: SDL_test_crc32.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_font.obj: SDL_test_font.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_fuzzer.obj: SDL_test_fuzzer.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_harness.obj: SDL_test_harness.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_imageBlit.obj: SDL_test_imageBlit.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_imageBlitBlend.obj: SDL_test_imageBlitBlend.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_imageFace.obj: SDL_test_imageFace.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_imagePrimitives.obj: SDL_test_imagePrimitives.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_imagePrimitivesBlend.obj: SDL_test_imagePrimitivesBlend.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_log.obj: SDL_test_log.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_md5.obj: SDL_test_md5.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_random.obj: SDL_test_random.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_memory.obj: SDL_test_memory.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< + +build_tlib: .symbolic + @echo * Compiling testlib objects +$(TLIB): build_tlib $(TOBJS) + @echo * Creating: $@ + wlib -q -b -n -c -pa -s -t -zld -ii -io $@ $(TOBJS) + +$(LNKFILE): Makefile.w32 + @echo * Creating linker file: $@ + @%create $@ + @%append $@ SYSTEM nt_dll INITINSTANCE TERMINSTANCE + @%append $@ NAME $(DLLFILE) + @for %i in ($(OBJS)) do @%append $@ FILE %i + @for %i in ($(LIBS)) do @%append $@ LIB %i + @%append $@ EXPORT=src/dynapi/SDL2.exports + @%append $@ OPTION QUIET + @%append $@ OPTION IMPF=$(EXPFILE) + @%append $@ OPTION MAP=$(LIBHOME)/$^&.map + @%append $@ OPTION DESCRIPTION '@$#libsdl org:$(VERSION)$#@$(DESCRIPTION)' + @%append $@ OPTION ELIMINATE + @%append $@ OPTION OSNAME='Windows NT' + @%append $@ OPTION SHOWDEAD + +clean: .SYMBOLIC + @echo * Clean: $(LIBNAME) + @if exist *.obj rm *.obj + @if exist *.err rm *.err + @if exist $(LNKFILE) rm $(LNKFILE) + +distclean: .SYMBOLIC clean + @if exist $(LIBHOME)/*.exp rm $(LIBHOME)/*.exp + @if exist $(LIBHOME)/*.map rm $(LIBHOME)/*.map + @if exist $(LIBFILE) rm $(LIBFILE) + @if exist $(DLLFILE) rm $(DLLFILE) + @if exist $(TLIB) rm $(TLIB) diff --git a/VisualC-WinRT/SDL-UWP.vcxproj b/VisualC-WinRT/SDL-UWP.vcxproj index c5c9aeeb5..77769355e 100644 --- a/VisualC-WinRT/SDL-UWP.vcxproj +++ b/VisualC-WinRT/SDL-UWP.vcxproj @@ -145,6 +145,7 @@ + diff --git a/VisualC-WinRT/SDL-UWP.vcxproj.filters b/VisualC-WinRT/SDL-UWP.vcxproj.filters index b9a9f823b..b05397673 100644 --- a/VisualC-WinRT/SDL-UWP.vcxproj.filters +++ b/VisualC-WinRT/SDL-UWP.vcxproj.filters @@ -330,6 +330,9 @@ Source Files + + Source Files + Source Files diff --git a/VisualC/SDL/SDL.vcxproj b/VisualC/SDL/SDL.vcxproj index 0d1ab307c..1e2556155 100644 --- a/VisualC/SDL/SDL.vcxproj +++ b/VisualC/SDL/SDL.vcxproj @@ -370,6 +370,7 @@ + diff --git a/VisualC/SDL/SDL.vcxproj.filters b/VisualC/SDL/SDL.vcxproj.filters index 12162e458..bd20ded8c 100644 --- a/VisualC/SDL/SDL.vcxproj.filters +++ b/VisualC/SDL/SDL.vcxproj.filters @@ -825,6 +825,7 @@ + diff --git a/VisualC/tests/controllermap/controllermap.vcxproj b/VisualC/tests/controllermap/controllermap.vcxproj index 20cf8dc11..66d8ef1fa 100644 --- a/VisualC/tests/controllermap/controllermap.vcxproj +++ b/VisualC/tests/controllermap/controllermap.vcxproj @@ -271,6 +271,7 @@ + diff --git a/VisualC/tests/loopwave/loopwave.vcxproj b/VisualC/tests/loopwave/loopwave.vcxproj index ccc7c3b56..c3fbf1c54 100644 --- a/VisualC/tests/loopwave/loopwave.vcxproj +++ b/VisualC/tests/loopwave/loopwave.vcxproj @@ -203,6 +203,7 @@ + @@ -227,4 +228,4 @@ - \ No newline at end of file + diff --git a/VisualC/tests/testgamecontroller/testgamecontroller.vcxproj b/VisualC/tests/testgamecontroller/testgamecontroller.vcxproj index 649aad915..d3710e293 100644 --- a/VisualC/tests/testgamecontroller/testgamecontroller.vcxproj +++ b/VisualC/tests/testgamecontroller/testgamecontroller.vcxproj @@ -271,6 +271,7 @@ + diff --git a/VisualC/tests/testoverlay2/testoverlay2.vcxproj b/VisualC/tests/testoverlay2/testoverlay2.vcxproj index 10e74b27e..e412a1dc3 100644 --- a/VisualC/tests/testoverlay2/testoverlay2.vcxproj +++ b/VisualC/tests/testoverlay2/testoverlay2.vcxproj @@ -217,6 +217,7 @@ + diff --git a/VisualC/tests/testrendertarget/testrendertarget.vcxproj b/VisualC/tests/testrendertarget/testrendertarget.vcxproj index 2d2d57bf1..e9ed5defa 100644 --- a/VisualC/tests/testrendertarget/testrendertarget.vcxproj +++ b/VisualC/tests/testrendertarget/testrendertarget.vcxproj @@ -241,8 +241,9 @@ + - \ No newline at end of file + diff --git a/VisualC/tests/testscale/testscale.vcxproj b/VisualC/tests/testscale/testscale.vcxproj index bd2ef383c..a42738bd0 100644 --- a/VisualC/tests/testscale/testscale.vcxproj +++ b/VisualC/tests/testscale/testscale.vcxproj @@ -241,8 +241,9 @@ + - \ No newline at end of file + diff --git a/VisualC/tests/testsprite2/testsprite2.vcxproj b/VisualC/tests/testsprite2/testsprite2.vcxproj index 13a3245f9..5ef2e117f 100644 --- a/VisualC/tests/testsprite2/testsprite2.vcxproj +++ b/VisualC/tests/testsprite2/testsprite2.vcxproj @@ -223,8 +223,9 @@ + - \ No newline at end of file + diff --git a/WhatsNew.txt b/WhatsNew.txt index 2d4c5c7f4..401b0a754 100644 --- a/WhatsNew.txt +++ b/WhatsNew.txt @@ -1,6 +1,31 @@ This is a list of major changes in SDL's version history. +--------------------------------------------------------------------------- +2.24.0: +--------------------------------------------------------------------------- + +General: +* New version numbering scheme, similar to GLib and Flatpak. + * An even number in the minor version (second component) indicates + a production-ready stable release such as 2.24.0, which would have + been 2.0.24 under the old system. + * The patchlevel (micro version, third component) indicates a + bugfix-only update: for example, 2.24.1 would be a bugfix-only + release to fix bugs in 2.24.0, without adding new features. + * An odd number in the minor version indicates a prerelease such + as 2.23.0. Stable distributions should not use these prereleases. + * The patchlevel indicates successive prereleases, for example + 2.23.1 and 2.23.2 would be prereleases during development of + the SDL 2.24.0 stable release. +* Added SDL_bsearch() to the stdlib routines +* Added functions to get the platform dependent name for a joystick or game controller: + * SDL_JoystickPathForIndex() + * SDL_JoystickPath() + * SDL_GameControllerPathForIndex() + * SDL_GameControllerPath() +* Added joystick event SDL_JOYBATTERYUPDATED for when battery status changes. + --------------------------------------------------------------------------- 2.0.22: --------------------------------------------------------------------------- diff --git a/Xcode/SDL/Info-Framework.plist b/Xcode/SDL/Info-Framework.plist index 49a711322..bb7986b87 100644 --- a/Xcode/SDL/Info-Framework.plist +++ b/Xcode/SDL/Info-Framework.plist @@ -19,10 +19,10 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.0.22 + 2.23.0 CFBundleSignature SDLX CFBundleVersion - 2.0.22 + 2.23.0 diff --git a/Xcode/SDL/SDL.xcodeproj/project.pbxproj b/Xcode/SDL/SDL.xcodeproj/project.pbxproj index 8858cfdd9..c6001f1ef 100644 --- a/Xcode/SDL/SDL.xcodeproj/project.pbxproj +++ b/Xcode/SDL/SDL.xcodeproj/project.pbxproj @@ -3469,13 +3469,13 @@ F395C1A22569C68F00942BFF /* SDL_iokitjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = F395C1922569C68E00942BFF /* SDL_iokitjoystick.c */; }; F395C1A32569C68F00942BFF /* SDL_iokitjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = F395C1922569C68E00942BFF /* SDL_iokitjoystick.c */; }; F395C1A42569C68F00942BFF /* SDL_iokitjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = F395C1922569C68E00942BFF /* SDL_iokitjoystick.c */; }; - F395C1B12569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; + F395C1B12569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; F395C1B22569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; F395C1B32569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; - F395C1B42569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; + F395C1B42569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; F395C1B52569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; F395C1B62569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; - F395C1B72569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; + F395C1B72569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; F395C1B82569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; F395C1B92569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; F395C1BA2569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F395C1B02569C6A000942BFF /* SDL_mfijoystick_c.h */; }; @@ -7172,6 +7172,7 @@ A7D88ABF23E2437C00DCD162 /* Sources */, A7D88B4623E2437C00DCD162 /* Frameworks */, A75FDB9F23E4CAFA00529352 /* Embed Frameworks */, + F3ED8107281DB8E600C33C5B /* Convert SDL includes to SDL Framework includes */, ); buildRules = ( ); @@ -7193,6 +7194,7 @@ A7D88C7823E24BED00DCD162 /* Sources */, A7D88D0423E24BED00DCD162 /* Frameworks */, A75FDBA223E4CAFF00529352 /* Embed Frameworks */, + F3ED8108281DB8F200C33C5B /* Convert SDL includes to SDL Framework includes */, ); buildRules = ( ); @@ -7234,6 +7236,7 @@ BECDF62C0761BA81005FE872 /* Sources */, BECDF6680761BA81005FE872 /* Frameworks */, A75FDB9C23E4CAEF00529352 /* Embed Frameworks */, + F3ED8106281DB8A500C33C5B /* Convert SDL includes to SDL Framework includes */, ); buildRules = ( ); @@ -7424,6 +7427,60 @@ shellPath = /bin/sh; shellScript = "# Sign framework\nif [ \"$SDL_CODESIGN_IDENTITY\" != \"\" ]; then\n codesign --force --deep --sign \"$SDL_CODESIGN_IDENTITY\" $TARGET_BUILD_DIR/SDL2.framework/Versions/A || exit $?\nfi\n\n# clean up the framework, remove headers, extra files\nmkdir -p build/dmg-tmp\ncp -a $TARGET_BUILD_DIR/SDL2.framework build/dmg-tmp/\n\ncp pkg-support/resources/License.txt build/dmg-tmp\ncp pkg-support/resources/ReadMe.txt build/dmg-tmp\n\n# remove the .DS_Store files if any (we may want to provide one in the future for fancy .dmgs)\nfind build/dmg-tmp -name .DS_Store -exec rm -f \"{}\" \\;\n\n# for fancy .dmg\nmkdir -p build/dmg-tmp/.logo\ncp pkg-support/resources/SDL_DS_Store build/dmg-tmp/.DS_Store\ncp pkg-support/sdl_logo.pdf build/dmg-tmp/.logo\n\n# create the dmg\nhdiutil create -ov -fs HFS+ -volname SDL2 -srcfolder build/dmg-tmp build/SDL2.dmg\n\n# clean up\nrm -rf build/dmg-tmp\n"; }; + F3ED8106281DB8A500C33C5B /* Convert SDL includes to SDL Framework includes */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Convert SDL includes to SDL Framework includes"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "cd \"$BUILT_PRODUCTS_DIR/$PUBLIC_HEADERS_FOLDER_PATH\"\nsed -i '' -e 's,#include \"\\(.*\\)\",#include ,' *.h\n"; + }; + F3ED8107281DB8E600C33C5B /* Convert SDL includes to SDL Framework includes */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Convert SDL includes to SDL Framework includes"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "cd \"$BUILT_PRODUCTS_DIR/$PUBLIC_HEADERS_FOLDER_PATH\"\nsed -i '' -e 's,#include \"\\(.*\\)\",#include ,' *.h\n"; + }; + F3ED8108281DB8F200C33C5B /* Convert SDL includes to SDL Framework includes */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Convert SDL includes to SDL Framework includes"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "cd \"$BUILT_PRODUCTS_DIR/$PUBLIC_HEADERS_FOLDER_PATH\"\nsed -i '' -e 's,#include \"\\(.*\\)\",#include ,' *.h\n"; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -9131,6 +9188,7 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; @@ -9151,7 +9209,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEPLOYMENT_POSTPROCESSING = YES; DYLIB_COMPATIBILITY_VERSION = 1.0.0; - DYLIB_CURRENT_VERSION = 23.0.0; + DYLIB_CURRENT_VERSION = 2301.0.0; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_ALTIVEC_EXTENSIONS = YES; @@ -9180,7 +9238,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 10.6; + MACOSX_DEPLOYMENT_TARGET = 10.7; PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL2; PRODUCT_NAME = SDL2; STRIP_STYLE = "non-global"; @@ -9216,6 +9274,7 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; @@ -9235,7 +9294,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1.0.0; - DYLIB_CURRENT_VERSION = 23.0.0; + DYLIB_CURRENT_VERSION = 2301.0.0; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -9264,7 +9323,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 10.6; + MACOSX_DEPLOYMENT_TARGET = 10.7; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL2; PRODUCT_NAME = SDL2; diff --git a/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj b/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj index 8c524cc54..e7e1d23bc 100644 --- a/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj +++ b/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj @@ -4041,6 +4041,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_OBJC_ARC = YES; FRAMEWORK_SEARCH_PATHS = ( "$(SRCROOT)/../SDL/build/$(CONFIGURATION)", "$(HOME)/Library/Frameworks", @@ -4048,7 +4049,7 @@ ); GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../../include; - MACOSX_DEPLOYMENT_TARGET = 10.6; + MACOSX_DEPLOYMENT_TARGET = 10.7; }; name = Debug; }; @@ -4168,6 +4169,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_OBJC_ARC = YES; FRAMEWORK_SEARCH_PATHS = ( "$(SRCROOT)/../SDL/build/$(CONFIGURATION)", "$(HOME)/Library/Frameworks", @@ -4175,7 +4177,7 @@ ); GCC_GENERATE_DEBUGGING_SYMBOLS = NO; HEADER_SEARCH_PATHS = ../../include; - MACOSX_DEPLOYMENT_TARGET = 10.6; + MACOSX_DEPLOYMENT_TARGET = 10.7; }; name = Release; }; diff --git a/Xcode/SDLTest/TestDropFile-Info.plist b/Xcode/SDLTest/TestDropFile-Info.plist index 03e46b33b..c9f6cb835 100644 --- a/Xcode/SDLTest/TestDropFile-Info.plist +++ b/Xcode/SDLTest/TestDropFile-Info.plist @@ -30,6 +30,6 @@ CFBundleVersion 1.0 LSMinimumSystemVersion - 10.6 + 10.7 diff --git a/autogen.sh b/autogen.sh index daf160de5..dffcf4152 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,5 +1,7 @@ #!/bin/sh +set -e + echo "Generating build information using autoconf" echo "This may take a while ..." @@ -10,11 +12,7 @@ cd "$srcdir" # Regenerate configuration files cat acinclude/* >aclocal.m4 -if test "$AUTOCONF"x = x; then - AUTOCONF=autoconf -fi - -$AUTOCONF || exit 1 +"${AUTOCONF:-autoconf}" rm aclocal.m4 rm -rf autom4te.cache diff --git a/build-scripts/androidbuildlibs.sh b/build-scripts/androidbuildlibs.sh index 3e57b4710..dc7217293 100755 --- a/build-scripts/androidbuildlibs.sh +++ b/build-scripts/androidbuildlibs.sh @@ -33,22 +33,21 @@ lib= ndk_args= # Allow an external caller to specify locations. -for arg in $* -do - if [ "${arg:0:8}" == "NDK_OUT=" ]; then - obj=${arg#NDK_OUT=} - elif [ "${arg:0:13}" == "NDK_LIBS_OUT=" ]; then - lib=${arg#NDK_LIBS_OUT=} - else - ndk_args="$ndk_args $arg" - fi +for arg in $*; do + if [ "${arg:0:8}" == "NDK_OUT=" ]; then + obj=${arg#NDK_OUT=} + elif [ "${arg:0:13}" == "NDK_LIBS_OUT=" ]; then + lib=${arg#NDK_LIBS_OUT=} + else + ndk_args="$ndk_args $arg" + fi done if [ -z $obj ]; then - obj=$buildandroid/obj + obj=$buildandroid/obj fi if [ -z $lib ]; then - lib=$buildandroid/lib + lib=$buildandroid/lib fi for dir in $build $buildandroid $obj $lib; do @@ -64,11 +63,11 @@ done # ndk-build makefile segments that use them, e.g., default-application.mk. # For consistency, pass all values on the command line. ndk-build \ - NDK_PROJECT_PATH=null \ - NDK_OUT=$obj \ - NDK_LIBS_OUT=$lib \ - APP_BUILD_SCRIPT=Android.mk \ - APP_ABI="armeabi-v7a arm64-v8a x86 x86_64" \ - APP_PLATFORM=android-16 \ - APP_MODULES="SDL2 SDL2_main" \ - $ndk_args + NDK_PROJECT_PATH=null \ + NDK_OUT=$obj \ + NDK_LIBS_OUT=$lib \ + APP_BUILD_SCRIPT=Android.mk \ + APP_ABI="armeabi-v7a arm64-v8a x86 x86_64" \ + APP_PLATFORM=android-16 \ + APP_MODULES="SDL2 SDL2_main" \ + $ndk_args diff --git a/build-scripts/clang++-fat.sh b/build-scripts/clang++-fat.sh index d337109f9..41fdf1c33 100755 --- a/build-scripts/clang++-fat.sh +++ b/build-scripts/clang++-fat.sh @@ -6,11 +6,11 @@ DEVELOPER="`xcode-select -print-path`/Platforms/MacOSX.platform/Developer" -# Intel 64-bit compiler flags (10.6 runtime compatibility) -CLANG_COMPILE_X64="clang++ -arch x86_64 -mmacosx-version-min=10.6 \ +# Intel 64-bit compiler flags (10.7 runtime compatibility) +CLANG_COMPILE_X64="clang++ -arch x86_64 -mmacosx-version-min=10.7 \ -I/usr/local/include" -CLANG_LINK_X64="-mmacosx-version-min=10.6" +CLANG_LINK_X64="-mmacosx-version-min=10.7" # ARM 64-bit compiler flags (11.0 runtime compatibility) CLANG_COMPILE_ARM64="clang++ -arch arm64 -mmacosx-version-min=11.0 \ diff --git a/build-scripts/clang-fat.sh b/build-scripts/clang-fat.sh index 38c07275d..4d1d30a6f 100755 --- a/build-scripts/clang-fat.sh +++ b/build-scripts/clang-fat.sh @@ -6,12 +6,12 @@ DEVELOPER="`xcode-select -print-path`/Platforms/MacOSX.platform/Developer" -# Intel 64-bit compiler flags (10.6 runtime compatibility) -CLANG_COMPILE_X64="clang -arch x86_64 -mmacosx-version-min=10.6 \ --DMAC_OS_X_VERSION_MIN_REQUIRED=1060 \ +# Intel 64-bit compiler flags (10.7 runtime compatibility) +CLANG_COMPILE_X64="clang -arch x86_64 -mmacosx-version-min=10.7 \ +-DMAC_OS_X_VERSION_MIN_REQUIRED=1070 \ -I/usr/local/include" -CLANG_LINK_X64="-mmacosx-version-min=10.6" +CLANG_LINK_X64="-mmacosx-version-min=10.7" # ARM 64-bit compiler flags (11.0 runtime compatibility) CLANG_COMPILE_ARM64="clang -arch arm64 -mmacosx-version-min=11.0 \ diff --git a/build-scripts/config.guess b/build-scripts/config.guess index b7806a8cb..160ecf095 100755 --- a/build-scripts/config.guess +++ b/build-scripts/config.guess @@ -4,7 +4,7 @@ # shellcheck disable=SC2006,SC2268 # see below for rationale -timestamp='2022-01-03' +timestamp='2022-05-08' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -929,6 +929,9 @@ EOF i*:PW*:*) GUESS=$UNAME_MACHINE-pc-pw32 ;; + *:SerenityOS:*:*) + GUESS=$UNAME_MACHINE-pc-serenity + ;; *:Interix*:*) case $UNAME_MACHINE in x86) @@ -1148,16 +1151,27 @@ EOF ;; x86_64:Linux:*:*) set_cc_for_build + CPU=$UNAME_MACHINE LIBCABI=$LIBC if test "$CC_FOR_BUILD" != no_compiler_found; then - if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_X32 >/dev/null - then - LIBCABI=${LIBC}x32 - fi + ABI=64 + sed 's/^ //' << EOF > "$dummy.c" + #ifdef __i386__ + ABI=x86 + #else + #ifdef __ILP32__ + ABI=x32 + #endif + #endif +EOF + cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` + eval "$cc_set_abi" + case $ABI in + x86) CPU=i686 ;; + x32) LIBCABI=${LIBC}x32 ;; + esac fi - GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI + GUESS=$CPU-pc-linux-$LIBCABI ;; xtensa*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC diff --git a/build-scripts/fnsince.pl b/build-scripts/fnsince.pl index 6c69c5473..fde65c862 100755 --- a/build-scripts/fnsince.pl +++ b/build-scripts/fnsince.pl @@ -46,9 +46,15 @@ my @releases = sort { # this happens to work for how SDL versions things at the moment. my $current_release = $releases[-1]; -my @current_release_segments = split /\./, $current_release; -@current_release_segments[2] = '' . ($current_release_segments[2] + 2); -my $next_release = join('.', @current_release_segments); +my $next_release; + +if ($current_release eq '2.0.22') { # Hack for our jump from 2.0.22 to 2.24.0... + $next_release = '2.24.0'; +} else { + my @current_release_segments = split /\./, $current_release; + @current_release_segments[1] = '' . ($current_release_segments[1] + 2); + $next_release = join('.', @current_release_segments); +} #print("\n\nSORTED\n"); #foreach (@releases) { diff --git a/build-scripts/gen_audio_resampler_filter.c b/build-scripts/gen_audio_resampler_filter.c new file mode 100644 index 000000000..4a343fb63 --- /dev/null +++ b/build-scripts/gen_audio_resampler_filter.c @@ -0,0 +1,162 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + 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. +*/ + +/* + +Built with: + +gcc -o genfilter build-scripts/gen_audio_resampler_filter.c -lm && ./genfilter > src/audio/SDL_audio_resampler_filter.h + + */ + +/* + SDL's resampler uses a "bandlimited interpolation" algorithm: + https://ccrma.stanford.edu/~jos/resample/ + + This code pre-generates the kaiser tables so we don't have to do this at + run time, at a cost of about 20 kilobytes of static data in SDL. This code + used to be part of SDL itself and generated the tables on the first use, + but that was expensive to produce on platforms without floating point + hardware. +*/ + +#include +#include + +#define RESAMPLER_ZERO_CROSSINGS 5 +#define RESAMPLER_BITS_PER_SAMPLE 16 +#define RESAMPLER_SAMPLES_PER_ZERO_CROSSING (1 << ((RESAMPLER_BITS_PER_SAMPLE / 2) + 1)) +#define RESAMPLER_FILTER_SIZE ((RESAMPLER_SAMPLES_PER_ZERO_CROSSING * RESAMPLER_ZERO_CROSSINGS) + 1) + +/* This is a "modified" bessel function, so you can't use POSIX j0() */ +static double +bessel(const double x) +{ + const double xdiv2 = x / 2.0; + double i0 = 1.0f; + double f = 1.0f; + int i = 1; + + while (1) { + const double diff = pow(xdiv2, i * 2) / pow(f, 2); + if (diff < 1.0e-21f) { + break; + } + i0 += diff; + i++; + f *= (double) i; + } + + return i0; +} + +/* build kaiser table with cardinal sine applied to it, and array of differences between elements. */ +static void +kaiser_and_sinc(float *table, float *diffs, const int tablelen, const double beta) +{ + const int lenm1 = tablelen - 1; + const int lenm1div2 = lenm1 / 2; + int i; + + table[0] = 1.0f; + for (i = 1; i < tablelen; i++) { + const double kaiser = bessel(beta * sqrt(1.0 - pow(((i - lenm1) / 2.0) / lenm1div2, 2.0))) / bessel(beta); + table[tablelen - i] = (float) kaiser; + } + + for (i = 1; i < tablelen; i++) { + const float x = (((float) i) / ((float) RESAMPLER_SAMPLES_PER_ZERO_CROSSING)) * ((float) M_PI); + table[i] *= sinf(x) / x; + diffs[i - 1] = table[i] - table[i - 1]; + } + diffs[lenm1] = 0.0f; +} + + +static float ResamplerFilter[RESAMPLER_FILTER_SIZE]; +static float ResamplerFilterDifference[RESAMPLER_FILTER_SIZE]; + +static void +PrepareResampleFilter(void) +{ + /* if dB > 50, beta=(0.1102 * (dB - 8.7)), according to Matlab. */ + const double dB = 80.0; + const double beta = 0.1102 * (dB - 8.7); + kaiser_and_sinc(ResamplerFilter, ResamplerFilterDifference, RESAMPLER_FILTER_SIZE, beta); +} + +int main(void) +{ + int i; + + PrepareResampleFilter(); + + printf( + "/*\n" + " Simple DirectMedia Layer\n" + " Copyright (C) 1997-2022 Sam Lantinga \n" + "\n" + " This software is provided 'as-is', without any express or implied\n" + " warranty. In no event will the authors be held liable for any damages\n" + " arising from the use of this software.\n" + "\n" + " Permission is granted to anyone to use this software for any purpose,\n" + " including commercial applications, and to alter it and redistribute it\n" + " freely, subject to the following restrictions:\n" + "\n" + " 1. The origin of this software must not be misrepresented; you must not\n" + " claim that you wrote the original software. If you use this software\n" + " in a product, an acknowledgment in the product documentation would be\n" + " appreciated but is not required.\n" + " 2. Altered source versions must be plainly marked as such, and must not be\n" + " misrepresented as being the original software.\n" + " 3. This notice may not be removed or altered from any source distribution.\n" + "*/\n" + "\n" + "/* DO NOT EDIT, THIS FILE WAS GENERATED BY build-scripts/gen_audio_resampler_filter.c */\n" + "\n" + "#define RESAMPLER_ZERO_CROSSINGS %d\n" + "#define RESAMPLER_BITS_PER_SAMPLE %d\n" + "#define RESAMPLER_SAMPLES_PER_ZERO_CROSSING (1 << ((RESAMPLER_BITS_PER_SAMPLE / 2) + 1))\n" + "#define RESAMPLER_FILTER_SIZE ((RESAMPLER_SAMPLES_PER_ZERO_CROSSING * RESAMPLER_ZERO_CROSSINGS) + 1)\n" + "\n", RESAMPLER_ZERO_CROSSINGS, RESAMPLER_BITS_PER_SAMPLE + ); + + printf("static const float ResamplerFilter[RESAMPLER_FILTER_SIZE] = {\n"); + printf(" %.9ff", ResamplerFilter[0]); + for (i = 0; i < RESAMPLER_FILTER_SIZE-1; i++) { + printf("%s%.9ff", ((i % 5) == 4) ? ",\n " : ", ", ResamplerFilter[i+1]); + } + printf("\n};\n\n"); + + printf("static const float ResamplerFilterDifference[RESAMPLER_FILTER_SIZE] = {\n"); + printf(" %.9ff", ResamplerFilterDifference[0]); + for (i = 0; i < RESAMPLER_FILTER_SIZE-1; i++) { + printf("%s%.9ff", ((i % 5) == 4) ? ",\n " : ", ", ResamplerFilterDifference[i+1]); + } + printf("\n};\n\n"); + printf("/* vi: set ts=4 sw=4 expandtab: */\n\n"); + + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/build-scripts/update-copyright.sh b/build-scripts/update-copyright.sh index ea1f79875..c69ec7293 100755 --- a/build-scripts/update-copyright.sh +++ b/build-scripts/update-copyright.sh @@ -1,8 +1,7 @@ #!/bin/sh -find . -type f -exec grep -Il "Copyright" {} \; \ -| grep -v \.git \ -| while read file; \ -do \ - LC_ALL=C sed -b -i "s/\(.*Copyright.*\)[0-9]\{4\}\( *Sam Lantinga\)/\1`date +%Y`\2/" "$file"; \ +find . -type f -exec grep -Il "Copyright" {} \; \ +| grep -v \.git \ +| while read file; do \ + LC_ALL=C sed -b -i "s/\(.*Copyright.*\)[0-9]\{4\}\( *Sam Lantinga\)/\1`date +%Y`\2/" "$file"; \ done diff --git a/build-scripts/winrtbuild.ps1 b/build-scripts/winrtbuild.ps1 index 736e6e006..ab835815b 100644 --- a/build-scripts/winrtbuild.ps1 +++ b/build-scripts/winrtbuild.ps1 @@ -39,7 +39,7 @@ # # Base version of SDL, used for packaging purposes -$SDLVersion = "2.0.22" +$SDLVersion = "2.23.0" # Gets the .bat file that sets up an MSBuild environment, given one of # Visual Studio's, "PlatformToolset"s. diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake index 8dcb39265..c7b4b8887 100644 --- a/cmake/sdlchecks.cmake +++ b/cmake/sdlchecks.cmake @@ -393,7 +393,7 @@ endmacro() # - HAVE_SDL_LOADSO opt macro(CheckX11) if(SDL_X11) - foreach(_LIB X11 Xext Xcursor Xinerama Xi Xfixes Xrandr Xrender Xss Xxf86vm) + foreach(_LIB X11 Xext Xcursor Xi Xfixes Xrandr Xrender Xss) FindLibraryAndSONAME("${_LIB}") endforeach() @@ -415,7 +415,6 @@ macro(CheckX11) endif() check_include_file(X11/Xcursor/Xcursor.h HAVE_XCURSOR_H) - check_include_file(X11/extensions/Xinerama.h HAVE_XINERAMA_H) check_include_file(X11/extensions/XInput2.h HAVE_XINPUT2_H) check_include_file(X11/extensions/Xrandr.h HAVE_XRANDR_H) check_include_file(X11/extensions/Xfixes.h HAVE_XFIXES_H_) @@ -423,7 +422,6 @@ macro(CheckX11) check_include_file(X11/extensions/scrnsaver.h HAVE_XSS_H) check_include_file(X11/extensions/shape.h HAVE_XSHAPE_H) check_include_files("X11/Xlib.h;X11/extensions/Xdbe.h" HAVE_XDBE_H) - check_include_files("X11/Xlib.h;X11/extensions/xf86vmode.h" HAVE_XF86VM_H) check_include_files("X11/Xlib.h;X11/Xproto.h;X11/extensions/Xext.h" HAVE_XEXT_H) if(X11_LIB) @@ -504,16 +502,6 @@ macro(CheckX11) set(SDL_VIDEO_DRIVER_X11_XDBE 1) endif() - if(SDL_X11_XINERAMA AND HAVE_XINERAMA_H) - set(HAVE_X11_XINERAMA TRUE) - if(HAVE_X11_SHARED AND XINERAMA_LIB) - set(SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA "\"${XINERAMA_LIB_SONAME}\"") - else() - list(APPEND EXTRA_LIBS ${XINERAMA_LIB}) - endif() - set(SDL_VIDEO_DRIVER_X11_XINERAMA 1) - endif() - if(SDL_X11_XINPUT AND HAVE_XINPUT2_H) set(HAVE_X11_XINPUT TRUE) if(HAVE_X11_SHARED AND XI_LIB) @@ -584,16 +572,6 @@ macro(CheckX11) set(HAVE_X11_XSHAPE TRUE) endif() - if(SDL_X11_XVM AND HAVE_XF86VM_H) - if(HAVE_X11_SHARED AND XXF86VM_LIB) - set(SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE "\"${XXF86VM_LIB_SONAME}\"") - else() - list(APPEND EXTRA_LIBS ${XXF86VM_LIB}) - endif() - set(SDL_VIDEO_DRIVER_X11_XVIDMODE 1) - set(HAVE_X11_XVM TRUE) - endif() - set(CMAKE_REQUIRED_LIBRARIES) endif() endif() diff --git a/configure b/configure index f3ea813eb..3943176a0 100755 --- a/configure +++ b/configure @@ -878,13 +878,11 @@ with_x enable_x11_shared enable_video_x11_xcursor enable_video_x11_xdbe -enable_video_x11_xinerama enable_video_x11_xinput enable_video_x11_xfixes enable_video_x11_xrandr enable_video_x11_scrnsaver enable_video_x11_xshape -enable_video_x11_vm enable_video_vivante enable_video_cocoa enable_video_metal @@ -1668,8 +1666,6 @@ Optional Features: --enable-video-x11-xcursor enable X11 Xcursor support [default=yes] --enable-video-x11-xdbe enable X11 Xdbe support [default=yes] - --enable-video-x11-xinerama - enable X11 Xinerama support [default=yes] --enable-video-x11-xinput enable X11 XInput extension for manymouse, tablets, etc [default=yes] @@ -1682,7 +1678,6 @@ Optional Features: enable X11 screensaver extension [default=yes] --enable-video-x11-xshape enable X11 XShape support [default=yes] - --enable-video-x11-vm use X11 VM extension for fullscreen [default=yes] --enable-video-vivante use Vivante EGL video driver [default=yes] --enable-video-cocoa use Cocoa video driver [default=yes] --enable-video-metal include Metal support [default=yes] @@ -2854,23 +2849,22 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. orig_CFLAGS="$CFLAGS" -# -# Making releases: -# Edit include/SDL_version.h and change the version, then: -# SDL_MICRO_VERSION += 1; -# SDL_INTERFACE_AGE += 1; -# SDL_BINARY_AGE += 1; -# if any functions have been added, set SDL_INTERFACE_AGE to 0. -# if backwards compatibility has been broken, -# set SDL_BINARY_AGE and SDL_INTERFACE_AGE to 0. -# +# See docs/release_checklist.md SDL_MAJOR_VERSION=2 -SDL_MINOR_VERSION=0 -SDL_MICRO_VERSION=22 -SDL_INTERFACE_AGE=0 -SDL_BINARY_AGE=22 +SDL_MINOR_VERSION=23 +SDL_MICRO_VERSION=0 SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION +SDL_BINARY_AGE=`expr $SDL_MINOR_VERSION \* 100 + $SDL_MICRO_VERSION` +case "$SDL_MINOR_VERSION" in #( + *[02468]) : + SDL_INTERFACE_AGE="$SDL_MICRO_VERSION" ;; #( + *) : + SDL_INTERFACE_AGE=0 ;; #( + *) : + ;; +esac + @@ -12259,10 +12253,17 @@ CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS -LT_RELEASE=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION -LT_CURRENT=`expr $SDL_MICRO_VERSION - $SDL_INTERFACE_AGE` -LT_REVISION=$SDL_INTERFACE_AGE +# For historical reasons, the library name redundantly includes the major +# version twice: libSDL2-2.0.so.0. +# TODO: in SDL 3, stop using -release, which will simplify it to libSDL3.so.0 +LT_RELEASE=2.0 +# Increment this if there is an incompatible change - but if that happens, +# we should rename the library from SDL2 to SDL3, at which point this would +# reset to 0 anyway. +LT_MAJOR=0 LT_AGE=`expr $SDL_BINARY_AGE - $SDL_INTERFACE_AGE` +LT_CURRENT=`expr $LT_MAJOR + $LT_AGE` +LT_REVISION=$SDL_INTERFACE_AGE @@ -16968,6 +16969,22 @@ $as_echo "#define SDL_DEFAULT_ASSERT_LEVEL 3" >>confdefs.h ;; esac + +cat >>confdefs.h <<_ACEOF +#define SDL_BUILD_MAJOR_VERSION $SDL_MAJOR_VERSION +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define SDL_BUILD_MINOR_VERSION $SDL_MINOR_VERSION +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define SDL_BUILD_MICRO_VERSION $SDL_MICRO_VERSION +_ACEOF + + # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; @@ -17717,7 +17734,7 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi - for ac_func in malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove wcslen wcslcpy wcslcat _wcsdup wcsdup wcsstr wcscmp wcsncmp wcscasecmp _wcsicmp wcsncasecmp _wcsnicmp strlen strlcpy strlcat _strrev _strupr _strlwr index rindex strchr strrchr strstr strtok_r itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname getauxval elf_aux_info poll _Exit + for ac_func in malloc calloc realloc free getenv setenv putenv unsetenv bsearch qsort abs bcopy memset memcpy memmove wcslen wcslcpy wcslcat _wcsdup wcsdup wcsstr wcscmp wcsncmp wcscasecmp _wcsicmp wcsncasecmp _wcsnicmp strlen strlcpy strlcat _strrev _strupr _strlwr index rindex strchr strrchr strstr strtok_r itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname getauxval elf_aux_info poll _Exit do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -18229,9 +18246,6 @@ if test x$enable_assembly = xyes; then SUMMARY_modules="${SUMMARY_modules} assembly" -$as_echo "#define SDL_ASSEMBLY_ROUTINES 1" >>confdefs.h - - # Make sure that we don't generate floating point code that would # cause illegal instruction exceptions on older processors case "$host" in @@ -20368,6 +20382,40 @@ $as_echo "#define SDL_ARM_NEON_BLITTERS 1" >>confdefs.h fi } +CheckObjectiveCARC() +{ + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clang -fobjc-arc option" >&5 +$as_echo_n "checking for clang -fobjc-arc option... " >&6; } + have_clang_objc_arc=no + + save_CFLAGS="$CFLAGS" + CFLAGS="$save_CFLAGS -fobjc-arc" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + int x = 0; + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + have_clang_objc_arc=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_clang_objc_arc" >&5 +$as_echo "$have_clang_objc_arc" >&6; } + CFLAGS="$save_CFLAGS" + + if test x$have_clang_objc_arc = xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -fobjc-arc" + fi +} + CheckVisibilityHidden() { { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC -fvisibility=hidden option" >&5 @@ -21741,37 +21789,31 @@ fi x11_lib='/opt/X11/lib/libX11.6.dylib' x11ext_lib='/opt/X11/lib/libXext.6.dylib' xcursor_lib='/opt/X11/lib/libXcursor.1.dylib' - xinerama_lib='/opt/X11/lib/libXinerama.1.dylib' xinput_lib='/opt/X11/lib/libXi.6.dylib' xfixes_lib='/opt/X11/lib/libXfixes.3.dylib' xrandr_lib='/opt/X11/lib/libXrandr.2.dylib' xrender_lib='/opt/X11/lib/libXrender.1.dylib' xss_lib='/opt/X11/lib/libXss.1.dylib' - xvidmode_lib='/opt/X11/lib/libXxf86vm.1.dylib' ;; *-*-openbsd*) x11_lib='libX11.so' x11ext_lib='libXext.so' xcursor_lib='libXcursor.so' - xinerama_lib='libXinerama.so' xinput_lib='libXi.so' xfixes_lib='libXfixes.so' xrandr_lib='libXrandr.so' xrender_lib='libXrender.so' xss_lib='libXss.so' - xvidmode_lib='libXxf86vm.so' ;; *) x11_lib=`find_lib "libX11.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` x11ext_lib=`find_lib "libXext.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` xcursor_lib=`find_lib "libXcursor.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` - xinerama_lib=`find_lib "libXinerama.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` xinput_lib=`find_lib "libXi.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` xfixes_lib=`find_lib "libXfixes.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` xrandr_lib=`find_lib "libXrandr.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` xrender_lib=`find_lib "libXrender.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` xss_lib=`find_lib "libXss.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` - xvidmode_lib=`find_lib "libXxf86vm.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` ;; esac @@ -22023,88 +22065,6 @@ $as_echo "#define SDL_VIDEO_DRIVER_X11_XDBE 1" >>confdefs.h SUMMARY_video_x11="${SUMMARY_video_x11} xdbe" fi fi - # Check whether --enable-video-x11-xinerama was given. -if test "${enable_video_x11_xinerama+set}" = set; then : - enableval=$enable_video_x11_xinerama; -else - enable_video_x11_xinerama=yes -fi - - if test x$enable_video_x11_xinerama = xyes; then - definitely_enable_video_x11_xinerama=no - ac_fn_c_check_header_compile "$LINENO" "X11/extensions/Xinerama.h" "ac_cv_header_X11_extensions_Xinerama_h" "#include - -" -if test "x$ac_cv_header_X11_extensions_Xinerama_h" = xyes; then : - have_xinerama_h_hdr=yes -else - have_xinerama_h_hdr=no -fi - - - if test x$have_xinerama_h_hdr = xyes; then - if test x$enable_x11_shared = xyes && test x$xinerama_lib != x ; then - echo "-- dynamic libXinerama -> $xinerama_lib" - -cat >>confdefs.h <<_ACEOF -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA "$xinerama_lib" -_ACEOF - - definitely_enable_video_x11_xinerama=yes - else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XineramaQueryExtension in -lXinerama" >&5 -$as_echo_n "checking for XineramaQueryExtension in -lXinerama... " >&6; } -if ${ac_cv_lib_Xinerama_XineramaQueryExtension+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lXinerama $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char XineramaQueryExtension (); -int -main () -{ -return XineramaQueryExtension (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_Xinerama_XineramaQueryExtension=yes -else - ac_cv_lib_Xinerama_XineramaQueryExtension=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xinerama_XineramaQueryExtension" >&5 -$as_echo "$ac_cv_lib_Xinerama_XineramaQueryExtension" >&6; } -if test "x$ac_cv_lib_Xinerama_XineramaQueryExtension" = xyes; then : - have_xinerama_lib=yes -fi - - if test x$have_xinerama_lib = xyes ; then - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lXinerama" - definitely_enable_video_x11_xinerama=yes - fi - fi - fi - fi - if test x$definitely_enable_video_x11_xinerama = xyes; then - -$as_echo "#define SDL_VIDEO_DRIVER_X11_XINERAMA 1" >>confdefs.h - - SUMMARY_video_x11="${SUMMARY_video_x11} xinerama" - fi # Check whether --enable-video-x11-xinput was given. if test "${enable_video_x11_xinput+set}" = set; then : enableval=$enable_video_x11_xinput; @@ -22517,88 +22477,6 @@ $as_echo "#define SDL_VIDEO_DRIVER_X11_XSHAPE 1" >>confdefs.h SUMMARY_video_x11="${SUMMARY_video_x11} xshape" fi fi - # Check whether --enable-video-x11-vm was given. -if test "${enable_video_x11_vm+set}" = set; then : - enableval=$enable_video_x11_vm; -else - enable_video_x11_vm=yes -fi - - if test x$enable_video_x11_vm = xyes; then - definitely_enable_video_x11_vm=no - ac_fn_c_check_header_compile "$LINENO" "X11/extensions/xf86vmode.h" "ac_cv_header_X11_extensions_xf86vmode_h" "#include - -" -if test "x$ac_cv_header_X11_extensions_xf86vmode_h" = xyes; then : - have_vm_h_hdr=yes -else - have_vm_h_hdr=no -fi - - - if test x$have_vm_h_hdr = xyes; then - if test x$enable_x11_shared = xyes && test x$xvidmode_lib != x ; then - echo "-- dynamic libXxf86vm -> $xvidmode_lib" - -cat >>confdefs.h <<_ACEOF -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE "$xvidmode_lib" -_ACEOF - - definitely_enable_video_x11_vm=yes - else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XF86VidModeQueryVersion in -lXxf86vm" >&5 -$as_echo_n "checking for XF86VidModeQueryVersion in -lXxf86vm... " >&6; } -if ${ac_cv_lib_Xxf86vm_XF86VidModeQueryVersion+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lXxf86vm $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char XF86VidModeQueryVersion (); -int -main () -{ -return XF86VidModeQueryVersion (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_Xxf86vm_XF86VidModeQueryVersion=yes -else - ac_cv_lib_Xxf86vm_XF86VidModeQueryVersion=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xxf86vm_XF86VidModeQueryVersion" >&5 -$as_echo "$ac_cv_lib_Xxf86vm_XF86VidModeQueryVersion" >&6; } -if test "x$ac_cv_lib_Xxf86vm_XF86VidModeQueryVersion" = xyes; then : - have_vm_lib=yes -fi - - if test x$have_vm_lib = xyes ; then - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lXxf86vm" - definitely_enable_video_x11_vm=yes - fi - fi - fi - fi - if test x$definitely_enable_video_x11_vm = xyes; then - -$as_echo "#define SDL_VIDEO_DRIVER_X11_XVIDMODE 1" >>confdefs.h - - SUMMARY_video_x11="${SUMMARY_video_x11} xvidmode" - fi fi fi if test x$have_x != xyes; then @@ -26607,6 +26485,7 @@ $as_echo "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h EXTRA_CFLAGS="$EXTRA_CFLAGS -DTARGET_API_MAC_CARBON" EXTRA_CFLAGS="$EXTRA_CFLAGS -DTARGET_API_MAC_OSX" + CheckObjectiveCARC CheckVisibilityHidden CheckDeclarationAfterStatement CheckDummyVideo diff --git a/configure.ac b/configure.ac index d80b9d3b7..59253ae99 100644 --- a/configure.ac +++ b/configure.ac @@ -10,23 +10,21 @@ dnl Save the CFLAGS to see whether they were passed in or generated orig_CFLAGS="$CFLAGS" dnl Set various version strings - taken gratefully from the GTk sources -# -# Making releases: -# Edit include/SDL_version.h and change the version, then: -# SDL_MICRO_VERSION += 1; -# SDL_INTERFACE_AGE += 1; -# SDL_BINARY_AGE += 1; -# if any functions have been added, set SDL_INTERFACE_AGE to 0. -# if backwards compatibility has been broken, -# set SDL_BINARY_AGE and SDL_INTERFACE_AGE to 0. -# +# See docs/release_checklist.md SDL_MAJOR_VERSION=2 -SDL_MINOR_VERSION=0 -SDL_MICRO_VERSION=22 -SDL_INTERFACE_AGE=0 -SDL_BINARY_AGE=22 +SDL_MINOR_VERSION=23 +SDL_MICRO_VERSION=0 SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION +SDL_BINARY_AGE=`expr $SDL_MINOR_VERSION \* 100 + $SDL_MICRO_VERSION` +AS_CASE(["$SDL_MINOR_VERSION"], + [*@<:@02468@:>@], + dnl Stable branch, 2.24.1 -> libSDL2-2.0.so.0.2400.1 + [SDL_INTERFACE_AGE="$SDL_MICRO_VERSION"], + [*], + dnl Development branch, 2.23.1 -> libSDL2-2.0.so.0.2301.0 + [SDL_INTERFACE_AGE=0]) + AC_SUBST(SDL_MAJOR_VERSION) AC_SUBST(SDL_MINOR_VERSION) AC_SUBST(SDL_MICRO_VERSION) @@ -38,10 +36,17 @@ AC_SUBST(SDL_VERSION) LT_INIT([win32-dll]) LT_LANG([Windows Resource]) -LT_RELEASE=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION -LT_CURRENT=`expr $SDL_MICRO_VERSION - $SDL_INTERFACE_AGE` -LT_REVISION=$SDL_INTERFACE_AGE +# For historical reasons, the library name redundantly includes the major +# version twice: libSDL2-2.0.so.0. +# TODO: in SDL 3, stop using -release, which will simplify it to libSDL3.so.0 +LT_RELEASE=2.0 +# Increment this if there is an incompatible change - but if that happens, +# we should rename the library from SDL2 to SDL3, at which point this would +# reset to 0 anyway. +LT_MAJOR=0 LT_AGE=`expr $SDL_BINARY_AGE - $SDL_INTERFACE_AGE` +LT_CURRENT=`expr $LT_MAJOR + $LT_AGE` +LT_REVISION=$SDL_INTERFACE_AGE m4_pattern_allow([^LT_]) AC_SUBST(LT_RELEASE) @@ -218,6 +223,10 @@ case "$enable_assertions" in ;; esac +AC_DEFINE_UNQUOTED([SDL_BUILD_MAJOR_VERSION], $SDL_MAJOR_VERSION, [ ]) +AC_DEFINE_UNQUOTED([SDL_BUILD_MINOR_VERSION], $SDL_MINOR_VERSION, [ ]) +AC_DEFINE_UNQUOTED([SDL_BUILD_MICRO_VERSION], $SDL_MICRO_VERSION, [ ]) + dnl See whether we can use gcc style dependency tracking AC_ARG_ENABLE(dependency-tracking, [AS_HELP_STRING([--enable-dependency-tracking], @@ -337,7 +346,7 @@ dnl Checks for library functions. AC_DEFINE(HAVE_MPROTECT, 1, [ ]) ],[]), ) - AC_CHECK_FUNCS(malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove wcslen wcslcpy wcslcat _wcsdup wcsdup wcsstr wcscmp wcsncmp wcscasecmp _wcsicmp wcsncasecmp _wcsnicmp strlen strlcpy strlcat _strrev _strupr _strlwr index rindex strchr strrchr strstr strtok_r itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname getauxval elf_aux_info poll _Exit) + AC_CHECK_FUNCS(malloc calloc realloc free getenv setenv putenv unsetenv bsearch qsort abs bcopy memset memcpy memmove wcslen wcslcpy wcslcat _wcsdup wcsdup wcsstr wcscmp wcsncmp wcscasecmp _wcsicmp wcsncasecmp _wcsnicmp strlen strlcpy strlcat _strrev _strupr _strlwr index rindex strchr strrchr strstr strtok_r itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname getauxval elf_aux_info poll _Exit) AC_CHECK_LIB(m, pow, [LIBS="$LIBS -lm"; EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lm"]) AC_CHECK_FUNCS(acos acosf asin asinf atan atanf atan2 atan2f ceil ceilf copysign copysignf cos cosf exp expf fabs fabsf floor floorf trunc truncf fmod fmodf log logf log10 log10f lround lroundf pow powf round roundf scalbn scalbnf sin sinf sqrt sqrtf tan tanf) @@ -574,8 +583,6 @@ AC_ARG_ENABLE(assembly, if test x$enable_assembly = xyes; then SUMMARY_modules="${SUMMARY_modules} assembly" - AC_DEFINE(SDL_ASSEMBLY_ROUTINES, 1, [ ]) - # Make sure that we don't generate floating point code that would # cause illegal instruction exceptions on older processors case "$host" in @@ -1423,6 +1430,26 @@ CheckNEON() fi } +dnl See if clang's -fobjc-arc supported. +dnl Reference: https://github.com/libsdl-org/SDL/pull/5632 +CheckObjectiveCARC() +{ + AC_MSG_CHECKING(for clang -fobjc-arc option) + have_clang_objc_arc=no + + save_CFLAGS="$CFLAGS" + CFLAGS="$save_CFLAGS -fobjc-arc" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + int x = 0; + ]],[])], [have_clang_objc_arc=yes],[]) + AC_MSG_RESULT($have_clang_objc_arc) + CFLAGS="$save_CFLAGS" + + if test x$have_clang_objc_arc = xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -fobjc-arc" + fi +} + dnl See if GCC's -fvisibility=hidden is supported (gcc4 and later, usually). dnl Details of this flag are here: http://gcc.gnu.org/wiki/Visibility CheckVisibilityHidden() @@ -1768,37 +1795,31 @@ CheckX11() x11_lib='/opt/X11/lib/libX11.6.dylib' x11ext_lib='/opt/X11/lib/libXext.6.dylib' xcursor_lib='/opt/X11/lib/libXcursor.1.dylib' - xinerama_lib='/opt/X11/lib/libXinerama.1.dylib' xinput_lib='/opt/X11/lib/libXi.6.dylib' xfixes_lib='/opt/X11/lib/libXfixes.3.dylib' xrandr_lib='/opt/X11/lib/libXrandr.2.dylib' xrender_lib='/opt/X11/lib/libXrender.1.dylib' xss_lib='/opt/X11/lib/libXss.1.dylib' - xvidmode_lib='/opt/X11/lib/libXxf86vm.1.dylib' ;; *-*-openbsd*) x11_lib='libX11.so' x11ext_lib='libXext.so' xcursor_lib='libXcursor.so' - xinerama_lib='libXinerama.so' xinput_lib='libXi.so' xfixes_lib='libXfixes.so' xrandr_lib='libXrandr.so' xrender_lib='libXrender.so' xss_lib='libXss.so' - xvidmode_lib='libXxf86vm.so' ;; *) x11_lib=[`find_lib "libX11.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] x11ext_lib=[`find_lib "libXext.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] xcursor_lib=[`find_lib "libXcursor.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] - xinerama_lib=[`find_lib "libXinerama.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] xinput_lib=[`find_lib "libXi.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] xfixes_lib=[`find_lib "libXfixes.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] xrandr_lib=[`find_lib "libXrandr.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] xrender_lib=[`find_lib "libXrender.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] xss_lib=[`find_lib "libXss.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] - xvidmode_lib=[`find_lib "libXxf86vm.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] ;; esac @@ -1910,34 +1931,6 @@ XFreeEventData(display, cookie); SUMMARY_video_x11="${SUMMARY_video_x11} xdbe" fi fi - AC_ARG_ENABLE(video-x11-xinerama, -[AS_HELP_STRING([--enable-video-x11-xinerama], [enable X11 Xinerama support [default=yes]])], - , enable_video_x11_xinerama=yes) - if test x$enable_video_x11_xinerama = xyes; then - definitely_enable_video_x11_xinerama=no - AC_CHECK_HEADER(X11/extensions/Xinerama.h, - have_xinerama_h_hdr=yes, - have_xinerama_h_hdr=no, - [#include - ]) - if test x$have_xinerama_h_hdr = xyes; then - if test x$enable_x11_shared = xyes && test x$xinerama_lib != x ; then - echo "-- dynamic libXinerama -> $xinerama_lib" - AC_DEFINE_UNQUOTED(SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA, "$xinerama_lib", [ ]) - definitely_enable_video_x11_xinerama=yes - else - AC_CHECK_LIB(Xinerama, XineramaQueryExtension, have_xinerama_lib=yes) - if test x$have_xinerama_lib = xyes ; then - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lXinerama" - definitely_enable_video_x11_xinerama=yes - fi - fi - fi - fi - if test x$definitely_enable_video_x11_xinerama = xyes; then - AC_DEFINE(SDL_VIDEO_DRIVER_X11_XINERAMA, 1, [ ]) - SUMMARY_video_x11="${SUMMARY_video_x11} xinerama" - fi AC_ARG_ENABLE(video-x11-xinput, [AS_HELP_STRING([--enable-video-x11-xinput], [enable X11 XInput extension for manymouse, tablets, etc [default=yes]])], , enable_video_x11_xinput=yes) @@ -2087,34 +2080,6 @@ dnl XRRScreenResources is only present in Xrandr >= 1.2, we use that SUMMARY_video_x11="${SUMMARY_video_x11} xshape" fi fi - AC_ARG_ENABLE(video-x11-vm, -[AS_HELP_STRING([--enable-video-x11-vm], [use X11 VM extension for fullscreen [default=yes]])], - , enable_video_x11_vm=yes) - if test x$enable_video_x11_vm = xyes; then - definitely_enable_video_x11_vm=no - AC_CHECK_HEADER(X11/extensions/xf86vmode.h, - have_vm_h_hdr=yes, - have_vm_h_hdr=no, - [#include - ]) - if test x$have_vm_h_hdr = xyes; then - if test x$enable_x11_shared = xyes && test x$xvidmode_lib != x ; then - echo "-- dynamic libXxf86vm -> $xvidmode_lib" - AC_DEFINE_UNQUOTED(SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE, "$xvidmode_lib", [ ]) - definitely_enable_video_x11_vm=yes - else - AC_CHECK_LIB(Xxf86vm, XF86VidModeQueryVersion, have_vm_lib=yes) - if test x$have_vm_lib = xyes ; then - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lXxf86vm" - definitely_enable_video_x11_vm=yes - fi - fi - fi - fi - if test x$definitely_enable_video_x11_vm = xyes; then - AC_DEFINE(SDL_VIDEO_DRIVER_X11_XVIDMODE, 1, [ ]) - SUMMARY_video_x11="${SUMMARY_video_x11} xvidmode" - fi fi fi if test x$have_x != xyes; then @@ -4250,6 +4215,7 @@ dnl BeOS support removed after SDL 2.0.1. Haiku still works. --ryan. EXTRA_CFLAGS="$EXTRA_CFLAGS -DTARGET_API_MAC_CARBON" EXTRA_CFLAGS="$EXTRA_CFLAGS -DTARGET_API_MAC_OSX" + CheckObjectiveCARC CheckVisibilityHidden CheckDeclarationAfterStatement CheckDummyVideo diff --git a/docs/README-linux.md b/docs/README-linux.md index 9c1b0c4c6..d440dee26 100644 --- a/docs/README-linux.md +++ b/docs/README-linux.md @@ -3,8 +3,8 @@ Linux By default SDL will only link against glibc, the rest of the features will be enabled dynamically at runtime depending on the available features on the target -system. So, for example if you built SDL with Xinerama support and the target -system does not have the Xinerama libraries installed, it will be disabled +system. So, for example if you built SDL with XRandR support and the target +system does not have the XRandR libraries installed, it will be disabled at runtime, and you won't get a missing library error, at least with the default configuration parameters. @@ -17,7 +17,7 @@ Ubuntu 20.04, all available features enabled: sudo apt-get install build-essential git make cmake autoconf automake \ libtool pkg-config libasound2-dev libpulse-dev libaudio-dev libjack-dev \ libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev \ - libxinerama-dev libxxf86vm-dev libxss-dev libgl1-mesa-dev libdbus-1-dev \ + libxss-dev libgl1-mesa-dev libdbus-1-dev \ libudev-dev libgles2-mesa-dev libegl1-mesa-dev libibus-1.0-dev \ fcitx-libs-dev libsamplerate0-dev libsndio-dev libwayland-dev \ libxkbcommon-dev libdrm-dev libgbm-dev @@ -27,12 +27,11 @@ Fedora 35, all available features enabled: sudo yum install gcc git-core make cmake autoconf automake libtool \ alsa-lib-devel pulseaudio-libs-devel nas-devel pipewire-devel \ libX11-devel libXext-devel libXrandr-devel libXcursor-devel libXfixes-devel \ - libXi-devel libXinerama-devel libXxf86vm-devel libXScrnSaver-devel \ - dbus-devel ibus-devel fcitx-devel systemd-devel mesa-libGL-devel \ - libxkbcommon-devel mesa-libGLES-devel mesa-libEGL-devel vulkan-devel \ - wayland-devel wayland-protocols-devel libdrm-devel mesa-libgbm-devel \ - libusb-devel pipewire-jack-audio-connection-kit-devel libdecor-devel \ - libsamplerate-devel + libXi-devel libXScrnSaver-devel dbus-devel ibus-devel fcitx-devel \ + systemd-devel mesa-libGL-devel libxkbcommon-devel mesa-libGLES-devel \ + mesa-libEGL-devel vulkan-devel wayland-devel wayland-protocols-devel \ + libdrm-devel mesa-libgbm-devel libusb-devel libdecor-devel \ + libsamplerate-devel pipewire-jack-audio-connection-kit-devel \ NOTES: - This includes all the audio targets except arts and esd, because Ubuntu diff --git a/docs/README-macos.md b/docs/README-macos.md index 9d2c6a921..91987ade2 100644 --- a/docs/README-macos.md +++ b/docs/README-macos.md @@ -43,15 +43,14 @@ make sudo make install ``` -This script builds SDL with 10.6 ABI compatibility on 64-bit Intel and 11.0 +This script builds SDL with 10.7 ABI compatibility on 64-bit Intel and 11.0 ABI compatibility on ARM64 architectures. For best compatibility you should compile your application the same way. -Please note that building SDL requires at least Xcode 4.6 and the 10.7 SDK -(even if you target back to 10.6 systems). PowerPC support for Mac OS X has -been officially dropped as of SDL 2.0.2. 32-bit Intel, using an older Xcode -release, is still supported at the time of this writing, but current Xcode -releases no longer support it, and eventually neither will SDL. +Please note that building SDL requires at least Xcode 4.6 and the 10.7 SDK. +PowerPC support for macOS has been officially dropped as of SDL 2.0.2. +32-bit Intel and macOS 10.6 runtime support has been officially dropped as +of SDL 2.24.0. To use the library once it's built, you essential have two possibilities: use the traditional autoconf/automake/make method, or use Xcode. diff --git a/docs/README-ngage.md b/docs/README-ngage.md new file mode 100644 index 000000000..83c2e3384 --- /dev/null +++ b/docs/README-ngage.md @@ -0,0 +1,44 @@ +Nokia N-Gage +============ + +SDL2 port for Symbian S60v1 and v2 with a main focus on the Nokia N-Gage +(Classic and QD) by [Michael Fitzmayer](https://github.com/mupfdev). + +Compiling +--------- + +SDL is part of the [N-Gage SDK.](https://github.com/ngagesdk) project. +The library is included in the +[toolchain](https://github.com/ngagesdk/ngage-toolchain) as a +sub-module. + +A complete example project based on SDL2 can be found in the GitHub +account of the SDK: [Wordle](https://github.com/ngagesdk/wordle). + +Current level of implementation +------------------------------- + +The video driver currently provides full screen video support with +keyboard input. + +At the moment only the software renderer works. + +Audio is not yet implemented. + +Acknowledgements +---------------- + +Thanks to Hannu Viitala, Kimmo Kinnunen and Markus Mertama for the +valuable insight into Symbian programming. Without the SDL 1.2 port +which was specially developed for CDoom (Doom for the Nokia 9210), this +adaptation would not have been possible. + +I would like to thank my friends +[Razvan](https://twitter.com/bewarerazvan) and [Dan +Whelan](https://danwhelan.ie/), for their continuous support. Without +you and the [N-Gage community](https://discord.gg/dbUzqJ26vs), I would +have lost my patience long ago. + +Last but not least, I would like to thank the development team of +[EKA2L1](https://12z1.com/) (an experimental Symbian OS emulator). Your +patience and support in troubleshooting helped me a lot. diff --git a/docs/README-raspberrypi.md b/docs/README-raspberrypi.md index 556b9f8d1..d2eddb862 100644 --- a/docs/README-raspberrypi.md +++ b/docs/README-raspberrypi.md @@ -63,7 +63,7 @@ Now, before chrooting into the ARM sysroot, you'll need to apply a workaround, edit $SYSROOT/etc/ld.so.preload and comment out all lines in it. sudo chroot $SYSROOT - apt-get install libudev-dev libasound2-dev libdbus-1-dev libraspberrypi0 libraspberrypi-bin libraspberrypi-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxinerama-dev libxxf86vm-dev libxss-dev + apt-get install libudev-dev libasound2-dev libdbus-1-dev libraspberrypi0 libraspberrypi-bin libraspberrypi-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxss-dev exit sudo umount $SYSROOT/dev sudo umount $SYSROOT/proc diff --git a/docs/README-versions.md b/docs/README-versions.md new file mode 100644 index 000000000..097dba1c7 --- /dev/null +++ b/docs/README-versions.md @@ -0,0 +1,60 @@ +# Versioning + +## Since 2.23.0 + +SDL follows an "odd/even" versioning policy, similar to GLib, GTK, Flatpak +and older versions of the Linux kernel: + +* The major version (first part) increases when backwards compatibility + is broken, which will happen infrequently. + +* If the minor version (second part) is divisible by 2 + (for example 2.24.x, 2.26.x), this indicates a version of SDL that + is believed to be stable and suitable for production use. + + * In stable releases, the patchlevel or micro version (third part) + indicates bugfix releases. Bugfix releases should not add or + remove ABI, so the ".0" release (for example 2.24.0) should be + forwards-compatible with all the bugfix releases from the + same cycle (for example 2.24.1). + + * The minor version increases when new API or ABI is added, or when + other significant changes are made. Newer minor versions are + backwards-compatible, but not fully forwards-compatible. + For example, programs built against SDL 2.24.x should work fine + with SDL 2.26.x, but programs built against SDL 2.26.x will not + necessarily work with 2.24.x. + +* If the minor version (second part) is not divisible by 2 + (for example 2.23.x, 2.25.x), this indicates a development prerelease + of SDL that is not suitable for stable software distributions. + Use with caution. + + * The patchlevel or micro version (third part) increases with + each prerelease. + + * Each prerelease might add new API and/or ABI. + + * Prereleases are backwards-compatible with older stable branches. + For example, 2.25.x will be backwards-compatible with 2.24.x. + + * Prereleases are not guaranteed to be backwards-compatible with + each other. For example, new API or ABI added in 2.25.1 + might be removed or changed in 2.25.2. + If this would be a problem for you, please do not use prereleases. + + * Only upgrade to a prerelease if you can guarantee that you will + promptly upgrade to the stable release that follows it. + For example, do not upgrade to 2.23.x unless you will be able to + upgrade to 2.24.0 when it becomes available. + + * Software distributions that have a freeze policy (in particular Linux + distributions with a release cycle, such as Debian and Fedora) + should usually only package stable releases, and not prereleases. + +## Before 2.23.0 + +Older versions of SDL followed a similar policy, but instead of the +odd/even rule applying to the minor version, it applied to the patchlevel +(micro version, third part). For example, 2.0.22 was a stable release +and 2.0.21 was a prerelease. diff --git a/docs/README.md b/docs/README.md index efbe3ad0e..d9953c08f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -47,10 +47,12 @@ More documentation and FAQs are available online at [the wiki](http://wiki.libsd - [PSP](README-psp.md) - [Raspberry Pi](README-raspberrypi.md) - [Touch](README-touch.md) +- [Versions](README-versions.md) - [WinCE](README-wince.md) - [Windows](README-windows.md) - [WinRT](README-winrt.md) - [PSVita](README-vita.md) +- [Nokia N-Gage](README-ngage.md) If you need help with the library, or just want to discuss SDL related issues, you can join the [SDL Discourse](https://discourse.libsdl.org/), diff --git a/docs/doxyfile b/docs/doxyfile index baf1c98de..7b80a3a8d 100644 --- a/docs/doxyfile +++ b/docs/doxyfile @@ -640,6 +640,7 @@ EXCLUDE = ../include/SDL_opengles2_gl2ext.h \ ../include/SDL_opengles.h \ ../include/SDL_opengl.h \ ../include/SDL_egl.h \ + ./release_checklist.md \ # The EXCLUDE_SYMLINKS tag can be used select whether or not files or diff --git a/docs/release_checklist.md b/docs/release_checklist.md new file mode 100644 index 000000000..bb38f4fec --- /dev/null +++ b/docs/release_checklist.md @@ -0,0 +1,91 @@ +# Release checklist + +## New feature release + +* Update `WhatsNew.txt` + +* Bump version number to 2.EVEN.0 in all these locations: + + * `configure.ac`, `CMakeLists.txt`: `SDL_*_VERSION` + * `Xcode/SDL/Info-Framework.plist`: `CFBundleShortVersionString`, + `CFBundleVersion` + * `Makefile.os2`: `VERSION` + * `build-scripts/winrtbuild.ps1`: `$SDLVersion` + * `include/SDL_version.h`: `SDL_*_VERSION`, `SDL_PATCHLEVEL` + * `src/main/windows/version.rc`: `FILEVERSION`, `PRODUCTVERSION`, + `FileVersion`, `ProductVersion` + +* Bump ABI version information + + * `CMakeLists.txt`, `Xcode/SDL/SDL.xcodeproj/project.pbxproj`: + `DYLIB_CURRENT_VERSION`, `DYLIB_COMPATIBILITY_VERSION` + * set first number in `DYLIB_CURRENT_VERSION` to + (100 * *minor*) + 1 + * set second number in `DYLIB_CURRENT_VERSION` to 0 + * if backwards compatibility has been broken, + increase `DYLIB_COMPATIBILITY_VERSION` (?) + +* Run test/versioning.sh to verify that everything is consistent + +* Regenerate `configure` + +* Do the release + +## New bugfix release + +* Check that no new API/ABI was added + + * If it was, do a new feature release (see above) instead + +* Bump version number from 2.Y.Z to 2.Y.(Z+1) (Y is even) + + * Same places as listed above + +* Bump ABI version information + + * `CMakeLists.txt`, `Xcode/SDL/SDL.xcodeproj/project.pbxproj`: + `DYLIB_CURRENT_VERSION`, `DYLIB_COMPATIBILITY_VERSION` + * set second number in `DYLIB_CURRENT_VERSION` to *patchlevel* + +* Run test/versioning.sh to verify that everything is consistent + +* Regenerate `configure` + +* Do the release + +## After a feature release + +* Create a branch like `release-2.24.x` + +* Bump version number to 2.ODD.0 for next development branch + + * Same places as listed above + +* Bump ABI version information + + * Same places as listed above + * Assume that the next feature release will contain new API/ABI + +* Run test/versioning.sh to verify that everything is consistent + +## New development prerelease + +* Bump version number from 2.Y.Z to 2.Y.(Z+1) (Y is odd) + + * Same places as listed above + +* Bump ABI version information + + * `CMakeLists.txt`, `Xcode/SDL/SDL.xcodeproj/project.pbxproj`: + `DYLIB_CURRENT_VERSION`, `DYLIB_COMPATIBILITY_VERSION` + * set first number in `DYLIB_CURRENT_VERSION` to + (100 * *minor*) + *patchlevel* + 1 + * set second number in `DYLIB_CURRENT_VERSION` to 0 + * if backwards compatibility has been broken, + increase `DYLIB_COMPATIBILITY_VERSION` (?) + +* Run test/versioning.sh to verify that everything is consistent + +* Regenerate `configure` + +* Do the release diff --git a/include/SDL_config.h b/include/SDL_config.h index 7afefabe2..749988515 100644 --- a/include/SDL_config.h +++ b/include/SDL_config.h @@ -43,6 +43,8 @@ #include "SDL_config_os2.h" #elif defined(__EMSCRIPTEN__) #include "SDL_config_emscripten.h" +#elif defined(__NGAGE__) +#include "SDL_config_ngage.h" #else /* This is a minimal configuration just to get SDL running on new platforms. */ #include "SDL_config_minimal.h" diff --git a/include/SDL_config.h.cmake b/include/SDL_config.h.cmake index ae9c777c9..6222a03ef 100644 --- a/include/SDL_config.h.cmake +++ b/include/SDL_config.h.cmake @@ -88,6 +88,7 @@ #cmakedefine HAVE_UNSETENV 1 #endif #cmakedefine HAVE_QSORT 1 +#cmakedefine HAVE_BSEARCH 1 #cmakedefine HAVE_ABS 1 #cmakedefine HAVE_BCOPY 1 #cmakedefine HAVE_MEMSET 1 @@ -424,22 +425,18 @@ #cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC @SDL_VIDEO_DRIVER_X11_DYNAMIC@ #cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT @SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT@ #cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR @SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR@ -#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA @SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA@ #cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 @SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2@ #cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES @SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES@ #cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR @SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR@ #cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS @SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS@ -#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE @SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE@ #cmakedefine SDL_VIDEO_DRIVER_X11_XCURSOR @SDL_VIDEO_DRIVER_X11_XCURSOR@ #cmakedefine SDL_VIDEO_DRIVER_X11_XDBE @SDL_VIDEO_DRIVER_X11_XDBE@ -#cmakedefine SDL_VIDEO_DRIVER_X11_XINERAMA @SDL_VIDEO_DRIVER_X11_XINERAMA@ #cmakedefine SDL_VIDEO_DRIVER_X11_XINPUT2 @SDL_VIDEO_DRIVER_X11_XINPUT2@ #cmakedefine SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH @SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH@ #cmakedefine SDL_VIDEO_DRIVER_X11_XFIXES @SDL_VIDEO_DRIVER_X11_XFIXES@ #cmakedefine SDL_VIDEO_DRIVER_X11_XRANDR @SDL_VIDEO_DRIVER_X11_XRANDR@ #cmakedefine SDL_VIDEO_DRIVER_X11_XSCRNSAVER @SDL_VIDEO_DRIVER_X11_XSCRNSAVER@ #cmakedefine SDL_VIDEO_DRIVER_X11_XSHAPE @SDL_VIDEO_DRIVER_X11_XSHAPE@ -#cmakedefine SDL_VIDEO_DRIVER_X11_XVIDMODE @SDL_VIDEO_DRIVER_X11_XVIDMODE@ #cmakedefine SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS @SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS@ #cmakedefine SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM @SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM@ #cmakedefine SDL_VIDEO_DRIVER_VITA @SDL_VIDEO_DRIVER_VITA@ @@ -508,7 +505,6 @@ #cmakedefine SDL_LOCALE_DUMMY @SDL_LOCALE_DUMMY@ /* Enable assembly routines */ -#cmakedefine SDL_ASSEMBLY_ROUTINES @SDL_ASSEMBLY_ROUTINES@ #cmakedefine SDL_ALTIVEC_BLITTERS @SDL_ALTIVEC_BLITTERS@ #cmakedefine SDL_ARM_SIMD_BLITTERS @SDL_ARM_SIMD_BLITTERS@ #cmakedefine SDL_ARM_NEON_BLITTERS @SDL_ARM_NEON_BLITTERS@ diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index d544b7edf..23a0982b7 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -92,6 +92,7 @@ #undef HAVE_UNSETENV #endif #undef HAVE_QSORT +#undef HAVE_BSEARCH #undef HAVE_ABS #undef HAVE_BCOPY #undef HAVE_MEMSET @@ -390,22 +391,18 @@ #undef SDL_VIDEO_DRIVER_X11_DYNAMIC #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR -#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS -#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE #undef SDL_VIDEO_DRIVER_X11_XCURSOR #undef SDL_VIDEO_DRIVER_X11_XDBE -#undef SDL_VIDEO_DRIVER_X11_XINERAMA #undef SDL_VIDEO_DRIVER_X11_XINPUT2 #undef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH #undef SDL_VIDEO_DRIVER_X11_XFIXES #undef SDL_VIDEO_DRIVER_X11_XRANDR #undef SDL_VIDEO_DRIVER_X11_XSCRNSAVER #undef SDL_VIDEO_DRIVER_X11_XSHAPE -#undef SDL_VIDEO_DRIVER_X11_XVIDMODE #undef SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS #undef SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM #undef SDL_VIDEO_DRIVER_NACL @@ -474,7 +471,6 @@ #undef SDL_LOCALE_DUMMY /* Enable assembly routines */ -#undef SDL_ASSEMBLY_ROUTINES #undef SDL_ALTIVEC_BLITTERS #undef SDL_ARM_SIMD_BLITTERS #undef SDL_ARM_NEON_BLITTERS diff --git a/include/SDL_config_android.h b/include/SDL_config_android.h index 4a13a3a53..5a9cfc045 100644 --- a/include/SDL_config_android.h +++ b/include/SDL_config_android.h @@ -60,6 +60,7 @@ #define HAVE_SETENV 1 #define HAVE_UNSETENV 1 #define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 #define HAVE_ABS 1 #define HAVE_BCOPY 1 #define HAVE_MEMSET 1 diff --git a/include/SDL_config_emscripten.h b/include/SDL_config_emscripten.h index 028777df1..989e1243a 100644 --- a/include/SDL_config_emscripten.h +++ b/include/SDL_config_emscripten.h @@ -69,6 +69,7 @@ #define HAVE_PUTENV 1 #define HAVE_UNSETENV 1 #define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 #define HAVE_ABS 1 #define HAVE_BCOPY 1 #define HAVE_MEMSET 1 diff --git a/include/SDL_config_iphoneos.h b/include/SDL_config_iphoneos.h index 0aa242563..48f9f9f9b 100644 --- a/include/SDL_config_iphoneos.h +++ b/include/SDL_config_iphoneos.h @@ -60,6 +60,7 @@ #define HAVE_SETENV 1 #define HAVE_UNSETENV 1 #define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 #define HAVE_ABS 1 #define HAVE_BCOPY 1 #define HAVE_MEMSET 1 @@ -117,7 +118,7 @@ #define HAVE_LROUNDF 1 #define HAVE_POW 1 #define HAVE_POWF 1 -#define HAVE_ROUND 1 +#define HAVE_ROUND 1 #define HAVE_ROUNDF 1 #define HAVE_SCALBN 1 #define HAVE_SCALBNF 1 diff --git a/include/SDL_config_macosx.h b/include/SDL_config_macosx.h index ff42e3d5f..023ecaae3 100644 --- a/include/SDL_config_macosx.h +++ b/include/SDL_config_macosx.h @@ -63,6 +63,7 @@ #define HAVE_PUTENV 1 #define HAVE_UNSETENV 1 #define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 #define HAVE_ABS 1 #define HAVE_BCOPY 1 #define HAVE_MEMSET 1 @@ -120,7 +121,7 @@ #define HAVE_LROUNDF 1 #define HAVE_POW 1 #define HAVE_POWF 1 -#define HAVE_ROUND 1 +#define HAVE_ROUND 1 #define HAVE_ROUNDF 1 #define HAVE_SCALBN 1 #define HAVE_SCALBNF 1 @@ -185,17 +186,13 @@ #undef SDL_VIDEO_DRIVER_X11 #define SDL_VIDEO_DRIVER_X11_DYNAMIC "/opt/X11/lib/libX11.6.dylib" #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT "/opt/X11/lib/libXext.6.dylib" -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA "/opt/X11/lib/libXinerama.1.dylib" #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 "/opt/X11/lib/libXi.6.dylib" #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR "/opt/X11/lib/libXrandr.2.dylib" #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS "/opt/X11/lib/libXss.1.dylib" -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE "/opt/X11/lib/libXxf86vm.1.dylib" #define SDL_VIDEO_DRIVER_X11_XDBE 1 -#define SDL_VIDEO_DRIVER_X11_XINERAMA 1 #define SDL_VIDEO_DRIVER_X11_XRANDR 1 #define SDL_VIDEO_DRIVER_X11_XSCRNSAVER 1 #define SDL_VIDEO_DRIVER_X11_XSHAPE 1 -#define SDL_VIDEO_DRIVER_X11_XVIDMODE 1 #define SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM 1 #ifdef MAC_OS_X_VERSION_10_8 @@ -272,7 +269,6 @@ #define SDL_FILESYSTEM_COCOA 1 /* Enable assembly routines */ -#define SDL_ASSEMBLY_ROUTINES 1 #ifdef __ppc__ #define SDL_ALTIVEC_BLITTERS 1 #endif diff --git a/include/SDL_config_ngage.h b/include/SDL_config_ngage.h new file mode 100644 index 000000000..a9d2d37ab --- /dev/null +++ b/include/SDL_config_ngage.h @@ -0,0 +1,89 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + 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_config_ngage_h_ +#define SDL_config_ngage_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; +typedef unsigned long uintptr_t; + +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_MATH_H 1 +#define HAVE_CEIL 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COS 1 +#define HAVE_EXP 1 +#define HAVE_FABS 1 +#define HAVE_FLOOR 1 +#define HAVE_LOG 1 +#define HAVE_LOG10 1 +#define HAVE_SCALBN 1 +#define HAVE_SIN 1 +#define HAVE_SQRT 1 +#define HAVE_TAN 1 +#define HAVE_MALLOC 1 +#define SDL_MAIN_NEEDED 1 +#define LACKS_SYS_MMAN_H 1 + +/* Enable the N-Gage thread support (src/thread/ngage/\*.c) */ +#define SDL_THREAD_NGAGE 1 + +/* Enable the N-Gage timer support (src/timer/ngage/\*.c) */ +#define SDL_TIMER_NGAGE 1 + +/* Enable the N-Gage video driver (src/video/ngage/\*.c) */ +#define SDL_VIDEO_DRIVER_NGAGE 1 + +/* Enable the dummy audio driver (src/audio/dummy/\*.c) */ +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable the stub joystick driver (src/joystick/dummy/\*.c) */ +#define SDL_JOYSTICK_DISABLED 1 + +/* Enable the stub haptic driver (src/haptic/dummy/\*.c) */ +#define SDL_HAPTIC_DISABLED 1 + +/* Enable the stub HIDAPI */ +#define SDL_HIDAPI_DISABLED 1 + +/* Enable the stub sensor driver (src/sensor/dummy/\*.c) */ +#define SDL_SENSOR_DISABLED 1 + +/* Enable the stub shared object loader (src/loadso/dummy/\*.c) */ +#define SDL_LOADSO_DISABLED 1 + +/* Enable the dummy filesystem driver (src/filesystem/dummy/\*.c) */ +#define SDL_FILESYSTEM_DUMMY 1 + +#endif /* SDL_config_ngage_h_ */ diff --git a/include/SDL_config_os2.h b/include/SDL_config_os2.h index 1728bd772..1583245ee 100644 --- a/include/SDL_config_os2.h +++ b/include/SDL_config_os2.h @@ -56,9 +56,6 @@ #define SDL_TIMER_OS2 1 #define SDL_FILESYSTEM_OS2 1 -/* Enable assembly routines */ -#define SDL_ASSEMBLY_ROUTINES 1 - /* use libsamplerate for audio rate conversion. */ /*#define HAVE_LIBSAMPLERATE_H 1 */ @@ -105,7 +102,11 @@ #define HAVE_GETENV 1 #define HAVE_SETENV 1 #define HAVE_PUTENV 1 +/* OpenWatcom requires specific calling conventions for qsort and bsearch */ +#ifndef __WATCOMC__ #define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 +#endif #define HAVE_ABS 1 #define HAVE_BCOPY 1 #define HAVE_MEMSET 1 diff --git a/include/SDL_config_pandora.h b/include/SDL_config_pandora.h index e0be390bc..01bbf49b0 100644 --- a/include/SDL_config_pandora.h +++ b/include/SDL_config_pandora.h @@ -65,6 +65,7 @@ #define HAVE_PUTENV 1 #define HAVE_UNSETENV 1 #define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 #define HAVE_ABS 1 #define HAVE_BCOPY 1 #define HAVE_MEMSET 1 diff --git a/include/SDL_config_windows.h b/include/SDL_config_windows.h index 770b19039..81fde40c8 100644 --- a/include/SDL_config_windows.h +++ b/include/SDL_config_windows.h @@ -97,6 +97,7 @@ typedef unsigned int uintptr_t; #define HAVE_DDRAW_H 1 #define HAVE_DINPUT_H 1 #define HAVE_DSOUND_H 1 +#ifndef __WATCOMC__ #define HAVE_DXGI_H 1 #define HAVE_XINPUT_H 1 #if defined(_WIN32_MAXVER) && _WIN32_MAXVER >= 0x0A00 /* Windows 10 SDK */ @@ -110,6 +111,7 @@ typedef unsigned int uintptr_t; #define HAVE_AUDIOCLIENT_H 1 #define HAVE_TPCSHRD_H 1 #define HAVE_SENSORSAPI_H 1 +#endif #if (defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64)) && (defined(_MSC_VER) && _MSC_VER >= 1600) #define HAVE_IMMINTRIN_H 1 #elif defined(__has_include) && (defined(__i386__) || defined(__x86_64)) @@ -136,7 +138,11 @@ typedef unsigned int uintptr_t; #define HAVE_REALLOC 1 #define HAVE_FREE 1 #define HAVE_ALLOCA 1 +/* OpenWatcom requires specific calling conventions for qsort and bsearch */ +#ifndef __WATCOMC__ #define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 +#endif #define HAVE_ABS 1 #define HAVE_MEMSET 1 #define HAVE_MEMCPY 1 @@ -167,37 +173,40 @@ typedef unsigned int uintptr_t; #define HAVE__WCSNICMP 1 #define HAVE__WCSDUP 1 #define HAVE_ACOS 1 -#define HAVE_ACOSF 1 #define HAVE_ASIN 1 -#define HAVE_ASINF 1 #define HAVE_ATAN 1 -#define HAVE_ATANF 1 #define HAVE_ATAN2 1 +#define HAVE_CEIL 1 +#define HAVE_COS 1 +#define HAVE_EXP 1 +#define HAVE_FABS 1 +#define HAVE_FLOOR 1 +#define HAVE_FMOD 1 +#define HAVE_LOG 1 +#define HAVE_LOG10 1 +#define HAVE_POW 1 +#define HAVE_SIN 1 +#define HAVE_SQRT 1 +#define HAVE_TAN 1 +#ifndef __WATCOMC__ +#define HAVE_ACOSF 1 +#define HAVE_ASINF 1 +#define HAVE_ATANF 1 #define HAVE_ATAN2F 1 #define HAVE_CEILF 1 #define HAVE__COPYSIGN 1 -#define HAVE_COS 1 #define HAVE_COSF 1 -#define HAVE_EXP 1 #define HAVE_EXPF 1 -#define HAVE_FABS 1 #define HAVE_FABSF 1 -#define HAVE_FLOOR 1 #define HAVE_FLOORF 1 -#define HAVE_FMOD 1 #define HAVE_FMODF 1 -#define HAVE_LOG 1 #define HAVE_LOGF 1 -#define HAVE_LOG10 1 #define HAVE_LOG10F 1 -#define HAVE_POW 1 #define HAVE_POWF 1 -#define HAVE_SIN 1 #define HAVE_SINF 1 -#define HAVE_SQRT 1 #define HAVE_SQRTF 1 -#define HAVE_TAN 1 #define HAVE_TANF 1 +#endif #if defined(_MSC_VER) /* These functions were added with the VC++ 2013 C runtime library */ #if _MSC_VER >= 1800 @@ -217,8 +226,18 @@ typedef unsigned int uintptr_t; #if _MSC_VER >= 1400 #define HAVE__FSEEKI64 1 #endif +#ifdef _USE_MATH_DEFINES +#define HAVE_M_PI 1 #endif -#if !defined(_MSC_VER) || defined(_USE_MATH_DEFINES) +#elif defined(__WATCOMC__) +#define HAVE__FSEEKI64 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_VSSCANF 1 +#define HAVE_ROUND 1 +#define HAVE_SCALBN 1 +#define HAVE_TRUNC 1 +#else #define HAVE_M_PI 1 #endif #else @@ -227,7 +246,9 @@ typedef unsigned int uintptr_t; #endif /* Enable various audio drivers */ +#if defined(HAVE_MMDEVICEAPI_H) && defined(HAVE_AUDIOCLIENT_H) #define SDL_AUDIO_DRIVER_WASAPI 1 +#endif #define SDL_AUDIO_DRIVER_DSOUND 1 #define SDL_AUDIO_DRIVER_WINMM 1 #define SDL_AUDIO_DRIVER_DISK 1 @@ -248,7 +269,11 @@ typedef unsigned int uintptr_t; #define SDL_HAPTIC_XINPUT 1 /* Enable the sensor driver */ +#ifdef HAVE_SENSORSAPI_H #define SDL_SENSOR_WINDOWS 1 +#else +#define SDL_SENSOR_DUMMY 1 +#endif /* Enable various shared object loading systems */ #define SDL_LOADSO_WINDOWS 1 @@ -300,11 +325,6 @@ typedef unsigned int uintptr_t; /* Enable filesystem support */ #define SDL_FILESYSTEM_WINDOWS 1 -/* Enable assembly routines (Win64 doesn't have inline asm) */ -#ifndef _WIN64 -#define SDL_ASSEMBLY_ROUTINES 1 -#endif - #endif /* SDL_config_windows_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/include/SDL_config_winrt.h b/include/SDL_config_winrt.h index f3901a597..75aef4ebb 100644 --- a/include/SDL_config_winrt.h +++ b/include/SDL_config_winrt.h @@ -123,6 +123,7 @@ typedef unsigned int uintptr_t; #define HAVE_FREE 1 #define HAVE_ALLOCA 1 #define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 #define HAVE_ABS 1 #define HAVE_MEMSET 1 #define HAVE_MEMCPY 1 @@ -256,9 +257,4 @@ typedef unsigned int uintptr_t; /* Enable system power support */ #define SDL_POWER_WINRT 1 -/* Enable assembly routines (Win64 doesn't have inline asm) */ -#ifndef _WIN64 -#define SDL_ASSEMBLY_ROUTINES 1 -#endif - #endif /* SDL_config_winrt_h_ */ diff --git a/include/SDL_cpuinfo.h b/include/SDL_cpuinfo.h index 1fc40991d..55050da26 100644 --- a/include/SDL_cpuinfo.h +++ b/include/SDL_cpuinfo.h @@ -494,7 +494,7 @@ extern DECLSPEC size_t SDLCALL SDL_SIMDGetAlignment(void); * * \since This function is available since SDL 2.0.10. * - * \sa SDL_SIMDAlignment + * \sa SDL_SIMDGetAlignment * \sa SDL_SIMDRealloc * \sa SDL_SIMDFree */ @@ -518,7 +518,7 @@ extern DECLSPEC void * SDLCALL SDL_SIMDAlloc(const size_t len); * * \since This function is available since SDL 2.0.14. * - * \sa SDL_SIMDAlignment + * \sa SDL_SIMDGetAlignment * \sa SDL_SIMDAlloc * \sa SDL_SIMDFree */ diff --git a/include/SDL_endian.h b/include/SDL_endian.h index 2866f4bea..e1c6b5ef4 100644 --- a/include/SDL_endian.h +++ b/include/SDL_endian.h @@ -87,6 +87,28 @@ _m_prefetch(void *__P) #endif /* __linux__ */ #endif /* !SDL_BYTEORDER */ +#ifndef SDL_FLOATWORDORDER /* Not defined in SDL_config.h? */ +/* predefs from newer gcc versions: */ +#if defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__) && defined(__FLOAT_WORD_ORDER__) +#if (__FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#define SDL_FLOATWORDORDER SDL_LIL_ENDIAN +#elif (__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__) +#define SDL_FLOATWORDORDER SDL_BIG_ENDIAN +#else +#error Unsupported endianness +#endif /**/ +#elif defined(__MAVERICK__) +/* For Maverick, float words are always little-endian. */ +#define SDL_FLOATWORDORDER SDL_LIL_ENDIAN +#elif (defined(__arm__) || defined(__thumb__)) && !defined(__VFP_FP__) && !defined(__ARM_EABI__) +/* For FPA, float words are always big-endian. */ +#define SDL_FLOATWORDORDER SDL_BIG_ENDIAN +#else +/* By default, assume that floats words follow the memory system mode. */ +#define SDL_FLOATWORDORDER SDL_BYTEORDER +#endif /* __FLOAT_WORD_ORDER__ */ +#endif /* !SDL_FLOATWORDORDER */ + #include "begin_code.h" /* Set up for C function definitions, even when using C++ */ diff --git a/include/SDL_events.h b/include/SDL_events.h index 7e469070e..c0fc9bb1a 100644 --- a/include/SDL_events.h +++ b/include/SDL_events.h @@ -118,6 +118,7 @@ typedef enum SDL_JOYBUTTONUP, /**< Joystick button released */ SDL_JOYDEVICEADDED, /**< A new joystick has been inserted into the system */ SDL_JOYDEVICEREMOVED, /**< An opened joystick has been removed */ + SDL_JOYBATTERYUPDATED, /**< Joystick battery level change */ /* Game controller events */ SDL_CONTROLLERAXISMOTION = 0x650, /**< Game controller axis motion */ @@ -395,6 +396,16 @@ typedef struct SDL_JoyDeviceEvent Sint32 which; /**< The joystick device index for the ADDED event, instance id for the REMOVED event */ } SDL_JoyDeviceEvent; +/** + * \brief Joysick battery level change event structure (event.jbattery.*) + */ +typedef struct SDL_JoyBatteryEvent +{ + Uint32 type; /**< ::SDL_JOYBATTERYUPDATED */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + SDL_JoystickPowerLevel level; /**< The joystick battery level */ +} SDL_JoyBatteryEvent; /** * \brief Game controller axis motion event structure (event.caxis.*) @@ -625,6 +636,7 @@ typedef union SDL_Event SDL_JoyHatEvent jhat; /**< Joystick hat event data */ SDL_JoyButtonEvent jbutton; /**< Joystick button event data */ SDL_JoyDeviceEvent jdevice; /**< Joystick device change event data */ + SDL_JoyBatteryEvent jbattery; /**< Joystick battery event data */ SDL_ControllerAxisEvent caxis; /**< Game Controller axis event data */ SDL_ControllerButtonEvent cbutton; /**< Game Controller button event data */ SDL_ControllerDeviceEvent cdevice; /**< Game Controller device event data */ diff --git a/include/SDL_gamecontroller.h b/include/SDL_gamecontroller.h index 548861083..6c2c52558 100644 --- a/include/SDL_gamecontroller.h +++ b/include/SDL_gamecontroller.h @@ -289,6 +289,25 @@ extern DECLSPEC SDL_bool SDLCALL SDL_IsGameController(int joystick_index); */ extern DECLSPEC const char *SDLCALL SDL_GameControllerNameForIndex(int joystick_index); +/** + * Get the implementation dependent path for the game controller. + * + * This function can be called before any controllers are opened. + * + * `joystick_index` is the same as the `device_index` passed to + * SDL_JoystickOpen(). + * + * \param joystick_index the device_index of a device, from zero to + * SDL_NumJoysticks()-1 + * \returns the implementation-dependent path for the game controller, or NULL + * if there is no path or the index is invalid. + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_GameControllerPath + */ +extern DECLSPEC const char *SDLCALL SDL_GameControllerPathForIndex(int joystick_index); + /** * Get the type of a game controller. * @@ -386,6 +405,23 @@ extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerFromPlayerIndex(in */ extern DECLSPEC const char *SDLCALL SDL_GameControllerName(SDL_GameController *gamecontroller); +/** + * Get the implementation-dependent path for an opened game controller. + * + * This is the same path as returned by SDL_GameControllerNameForIndex(), but + * it takes a controller identifier instead of the (unstable) device index. + * + * \param gamecontroller a game controller identifier previously returned by + * SDL_GameControllerOpen() + * \returns the implementation dependent path for the game controller, or NULL + * if there is no path or the identifier passed is invalid. + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_GameControllerPathForIndex + */ +extern DECLSPEC const char *SDLCALL SDL_GameControllerPath(SDL_GameController *gamecontroller); + /** * Get the type of this currently opened controller * diff --git a/include/SDL_hints.h b/include/SDL_hints.h index ea819c85d..83cfe89a6 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -392,13 +392,14 @@ extern "C" { #define SDL_HINT_ENABLE_STEAM_CONTROLLERS "SDL_ENABLE_STEAM_CONTROLLERS" /** - * \brief A variable controlling whether SDL logs all events pushed onto its internal queue. + * \brief A variable controlling verbosity of the logging of SDL events pushed onto the internal queue. * - * This variable can be set to the following values: + * This variable can be set to the following values, from least to most verbose: * * "0" - Don't log any events (default) - * "1" - Log all events except mouse and finger motion, which are pretty spammy. - * "2" - Log all events. + * "1" - Log most events (other than the really spammy ones). + * "2" - Include mouse and finger motion events. + * "3" - Include SDL_SysWMEvent events. * * This is generally meant to be used to debug SDL itself, but can be useful * for application developers that need better visibility into what is going @@ -871,6 +872,24 @@ extern "C" { */ #define SDL_HINT_JOYSTICK_DEVICE "SDL_JOYSTICK_DEVICE" + /** + * \brief A variable controlling whether joysticks on Linux will always treat 'hat' axis inputs (ABS_HAT0X - ABS_HAT3Y) as 8-way digital hats without checking whether they may be analog. + * + * This variable can be set to the following values: + * "0" - Only map hat axis inputs to digital hat outputs if the input axes appear to actually be digital (the default) + * "1" - Always handle the input axes numbered ABS_HAT0X to ABS_HAT3Y as digital hats + */ +#define SDL_HINT_LINUX_DIGITAL_HATS "SDL_LINUX_DIGITAL_HATS" + + /** + * \brief A variable controlling whether digital hats on Linux will apply deadzones to their underlying input axes or use unfiltered values. + * + * This variable can be set to the following values: + * "0" - Return digital hat values based on unfiltered input axis values + * "1" - Return digital hat values with deadzones on the input axes taken into account (the default) + */ +#define SDL_HINT_LINUX_HAT_DEADZONES "SDL_LINUX_HAT_DEADZONES" + /** * \brief A variable controlling whether to use the classic /dev/input/js* joystick interface or the newer /dev/input/event* joystick interface on Linux * @@ -1450,9 +1469,7 @@ extern "C" { * SDL_WINDOW_RESIZABLE windows will offer the "fullscreen" * button on their titlebars). * - * The default value is "1". Spaces are disabled regardless of this hint if - * the OS isn't at least Mac OS X Lion (10.7). This hint must be set before - * any windows are created. + * The default value is "1". This hint must be set before any windows are created. */ #define SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES "SDL_VIDEO_MAC_FULLSCREEN_SPACES" @@ -1590,13 +1607,11 @@ extern "C" { #define SDL_HINT_VIDEO_X11_WINDOW_VISUALID "SDL_VIDEO_X11_WINDOW_VISUALID" /** - * \brief A variable controlling whether the X11 Xinerama extension should be used. + * \brief A no-longer-used variable controlling whether the X11 Xinerama extension should be used. * - * This variable can be set to the following values: - * "0" - Disable Xinerama - * "1" - Enable Xinerama - * - * By default SDL will use Xinerama if it is available. + * Before SDL 2.0.24, this would let apps and users disable Xinerama support on X11. + * Now SDL never uses Xinerama, and does not check for this hint at all. + * The preprocessor define is left here for source compatibility. */ #define SDL_HINT_VIDEO_X11_XINERAMA "SDL_VIDEO_X11_XINERAMA" @@ -1607,18 +1622,16 @@ extern "C" { * "0" - Disable XRandR * "1" - Enable XRandR * - * By default SDL will not use XRandR because of window manager issues. + * By default SDL will use XRandR. */ #define SDL_HINT_VIDEO_X11_XRANDR "SDL_VIDEO_X11_XRANDR" /** - * \brief A variable controlling whether the X11 VidMode extension should be used. + * \brief A no-longer-used variable controlling whether the X11 VidMode extension should be used. * - * This variable can be set to the following values: - * "0" - Disable XVidMode - * "1" - Enable XVidMode - * - * By default SDL will use XVidMode if it is available. + * Before SDL 2.0.24, this would let apps and users disable XVidMode support on X11. + * Now SDL never uses XVidMode, and does not check for this hint at all. + * The preprocessor define is left here for source compatibility. */ #define SDL_HINT_VIDEO_X11_XVIDMODE "SDL_VIDEO_X11_XVIDMODE" diff --git a/include/SDL_joystick.h b/include/SDL_joystick.h index 07e2b1561..f10689f56 100644 --- a/include/SDL_joystick.h +++ b/include/SDL_joystick.h @@ -153,6 +153,7 @@ extern DECLSPEC void SDLCALL SDL_UnlockJoysticks(void); * \since This function is available since SDL 2.0.0. * * \sa SDL_JoystickName + * \sa SDL_JoystickPath * \sa SDL_JoystickOpen */ extern DECLSPEC int SDLCALL SDL_NumJoysticks(void); @@ -174,6 +175,23 @@ extern DECLSPEC int SDLCALL SDL_NumJoysticks(void); */ extern DECLSPEC const char *SDLCALL SDL_JoystickNameForIndex(int device_index); +/** + * Get the implementation dependent path of a joystick. + * + * This can be called before any joysticks are opened. + * + * \param device_index the index of the joystick to query (the N'th joystick + * on the system) + * \returns the path of the selected joystick. If no path can be found, this + * function returns NULL; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_JoystickPath + * \sa SDL_JoystickOpen + */ +extern DECLSPEC const char *SDLCALL SDL_JoystickPathForIndex(int device_index); + /** * Get the player index of a joystick, or -1 if it's not available This can be * called before any joysticks are opened. @@ -330,6 +348,54 @@ extern DECLSPEC int SDLCALL SDL_JoystickAttachVirtual(SDL_JoystickType type, int nbuttons, int nhats); +/** + * The structure that defines an extended virtual joystick description + * + * The caller must zero the structure and then initialize the version with `SDL_VIRTUAL_JOYSTICK_DESC_VERSION` before passing it to SDL_JoystickAttachVirtualEx() + * All other elements of this structure are optional and can be left 0. + * + * \sa SDL_JoystickAttachVirtualEx + */ +typedef struct SDL_VirtualJoystickDesc +{ + Uint16 version; /**< `SDL_VIRTUAL_JOYSTICK_DESC_VERSION` */ + Uint16 type; /**< `SDL_JoystickType` */ + Uint16 naxes; /**< the number of axes on this joystick */ + Uint16 nbuttons; /**< the number of buttons on this joystick */ + Uint16 nhats; /**< the number of hats on this joystick */ + Uint16 vendor_id; /**< the USB vendor ID of this joystick */ + Uint16 product_id; /**< the USB product ID of this joystick */ + Uint16 padding; /**< unused */ + Uint32 button_mask; /**< A mask of which buttons are valid for this controller + e.g. (1 << SDL_CONTROLLER_BUTTON_A) */ + Uint32 axis_mask; /**< A mask of which axes are valid for this controller + e.g. (1 << SDL_CONTROLLER_AXIS_LEFTX) */ + const char *name; /**< the name of the joystick */ + + void *userdata; /**< User data pointer passed to callbacks */ + void (SDLCALL *Update)(void *userdata); /**< Called when the joystick state should be updated */ + void (SDLCALL *SetPlayerIndex)(void *userdata, int player_index); /**< Called when the player index is set */ + int (SDLCALL *Rumble)(void *userdata, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble); /**< Implements SDL_JoystickRumble() */ + int (SDLCALL *RumbleTriggers)(void *userdata, Uint16 left_rumble, Uint16 right_rumble); /**< Implements SDL_JoystickRumbleTriggers() */ + int (SDLCALL *SetLED)(void *userdata, Uint8 red, Uint8 green, Uint8 blue); /**< Implements SDL_JoystickSetLED() */ + int (SDLCALL *SendEffect)(void *userdata, const void *data, int size); /**< Implements SDL_JoystickSendEffect() */ + +} SDL_VirtualJoystickDesc; + +/** + * \brief The current version of the SDL_VirtualJoystickDesc structure + */ +#define SDL_VIRTUAL_JOYSTICK_DESC_VERSION 1 + +/** + * Attach a new virtual joystick with extended properties. + * + * \returns the joystick's device index, or -1 if an error occurred. + * + * \since This function is available since SDL 2.24.0. + */ +extern DECLSPEC int SDLCALL SDL_JoystickAttachVirtualEx(const SDL_VirtualJoystickDesc *desc); + /** * Detach a virtual joystick. * @@ -419,6 +485,19 @@ extern DECLSPEC int SDLCALL SDL_JoystickSetVirtualHat(SDL_Joystick *joystick, in */ extern DECLSPEC const char *SDLCALL SDL_JoystickName(SDL_Joystick *joystick); +/** + * Get the implementation dependent path of a joystick. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the path of the selected joystick. If no path can be found, this + * function returns NULL; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_JoystickPathForIndex + */ +extern DECLSPEC const char *SDLCALL SDL_JoystickPath(SDL_Joystick *joystick); + /** * Get the player index of an opened joystick. * diff --git a/include/SDL_keycode.h b/include/SDL_keycode.h index 35602541a..65420f29f 100644 --- a/include/SDL_keycode.h +++ b/include/SDL_keycode.h @@ -318,7 +318,12 @@ typedef enum SDLK_APP2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_APP2), SDLK_AUDIOREWIND = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOREWIND), - SDLK_AUDIOFASTFORWARD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOFASTFORWARD) + SDLK_AUDIOFASTFORWARD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOFASTFORWARD), + + SDLK_SOFTLEFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SOFTLEFT), + SDLK_SOFTRIGHT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SOFTRIGHT), + SDLK_CALL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CALL), + SDLK_ENDCALL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_ENDCALL) } SDL_KeyCode; /** diff --git a/include/SDL_log.h b/include/SDL_log.h index dbbcb1e6f..1d8b20b62 100644 --- a/include/SDL_log.h +++ b/include/SDL_log.h @@ -47,9 +47,9 @@ extern "C" { /** - * \brief The maximum size of a log message + * \brief The maximum size of a log message prior to SDL 2.0.24 * - * Messages longer than the maximum size will be truncated + * As of 2.0.24 there is no limit to the length of SDL log messages. */ #define SDL_MAX_LOG_MESSAGE 4096 diff --git a/include/SDL_platform.h b/include/SDL_platform.h index 79b8b6f45..c0bccb093 100644 --- a/include/SDL_platform.h +++ b/include/SDL_platform.h @@ -65,11 +65,15 @@ #undef __LINUX__ /* do we need to do this? */ #define __ANDROID__ 1 #endif +#if defined(__NGAGE__) +#undef __NGAGE__ +#define __NGAGE__ 1 +#endif #if defined(__APPLE__) /* lets us know what version of Mac OS X we're compiling on */ -#include "AvailabilityMacros.h" -#include "TargetConditionals.h" +#include +#include /* Fix building with older SDKs that don't define these See this for more information: @@ -104,9 +108,9 @@ /* if not compiling for iOS */ #undef __MACOSX__ #define __MACOSX__ 1 -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 -# error SDL for Mac OS X only supports deploying on 10.6 and above. -#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1060 */ +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 +# error SDL for Mac OS X only supports deploying on 10.7 and above. +#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1070 */ #endif /* TARGET_OS_IPHONE */ #endif /* defined(__APPLE__) */ diff --git a/include/SDL_rect.h b/include/SDL_rect.h index b678c7a34..6c641c581 100644 --- a/include/SDL_rect.h +++ b/include/SDL_rect.h @@ -252,10 +252,10 @@ SDL_FORCE_INLINE SDL_bool SDL_FRectEmpty(const SDL_FRect *r) 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_fabsf(a->x - b->x) <= epsilon) && + (SDL_fabsf(a->y - b->y) <= epsilon) && + (SDL_fabsf(a->w - b->w) <= epsilon) && + (SDL_fabsf(a->h - b->h) <= epsilon)))) ? SDL_TRUE : SDL_FALSE; } diff --git a/include/SDL_render.h b/include/SDL_render.h index d859e3fd6..450b84d18 100644 --- a/include/SDL_render.h +++ b/include/SDL_render.h @@ -825,9 +825,13 @@ extern DECLSPEC int SDLCALL SDL_RenderSetLogicalSize(SDL_Renderer * renderer, in /** * Get device independent resolution for rendering. * - * This may return 0 for `w` and `h` if the SDL_Renderer has never had its - * logical size set by SDL_RenderSetLogicalSize() and never had a render - * target set. + * When using the main rendering target (eg no target texture is set): this + * may return 0 for `w` and `h` if the SDL_Renderer has never had its logical + * size set by SDL_RenderSetLogicalSize(). Otherwise it returns the logical + * width and height. + * + * When using a target texture: Never return 0 for `w` and `h` at first. Then + * it returns the logical width and height that are set. * * \param renderer a rendering context * \param w an int to be filled with the width diff --git a/include/SDL_rwops.h b/include/SDL_rwops.h index 71e5c8db8..30b69a806 100644 --- a/include/SDL_rwops.h +++ b/include/SDL_rwops.h @@ -45,9 +45,6 @@ extern "C" { #define SDL_RWOPS_JNIFILE 3U /**< Android asset */ #define SDL_RWOPS_MEMORY 4U /**< Memory stream */ #define SDL_RWOPS_MEMORY_RO 5U /**< Read-Only memory stream */ -#if defined(__VITA__) -#define SDL_RWOPS_VITAFILE 6U /**< Vita file */ -#endif /** * This is the read/write operation structure -- very basic. @@ -113,17 +110,6 @@ typedef struct SDL_RWops size_t left; } buffer; } windowsio; -#elif defined(__VITA__) - struct - { - int h; - struct - { - void *data; - size_t size; - size_t left; - } buffer; - } vitaio; #endif #ifdef HAVE_STDIO_H diff --git a/include/SDL_scancode.h b/include/SDL_scancode.h index 5b2c67c8f..aaa782f8d 100644 --- a/include/SDL_scancode.h +++ b/include/SDL_scancode.h @@ -402,6 +402,26 @@ typedef enum /* @} *//* Usage page 0x0C (additional media keys) */ + /** + * \name Mobile keys + * + * These are values that are often used on mobile phones. + */ + /* @{ */ + + SDL_SCANCODE_SOFTLEFT = 287, /**< Usually situated below the display on phones and + used as a multi-function feature key for selecting + a software defined function shown on the bottom left + of the display. */ + SDL_SCANCODE_SOFTRIGHT = 288, /**< Usually situated below the display on phones and + used as a multi-function feature key for selecting + a software defined function shown on the bottom right + of the display. */ + SDL_SCANCODE_CALL = 289, /**< Used for accepting phone calls. */ + SDL_SCANCODE_ENDCALL = 290, /**< Used for rejecting phone calls. */ + + /* @} *//* Mobile keys */ + /* Add any other keys here. */ SDL_NUM_SCANCODES = 512 /**< not a key, just marks the number of scancodes diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index 449e6445c..6ee15f144 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -115,6 +115,12 @@ char *alloca(); # endif #endif +#ifdef SIZE_MAX +# define SDL_SIZE_MAX SIZE_MAX +#else +# define SDL_SIZE_MAX ((size_t) -1) +#endif + /** * Check if the compiler supports a given builtin. * Supported by virtually all clang versions and recent gcc. Use this @@ -462,7 +468,8 @@ extern DECLSPEC int SDLCALL SDL_GetNumAllocations(void); extern DECLSPEC char *SDLCALL SDL_getenv(const char *name); extern DECLSPEC int SDLCALL SDL_setenv(const char *name, const char *value, int overwrite); -extern DECLSPEC void SDLCALL SDL_qsort(void *base, size_t nmemb, size_t size, int (*compare) (const void *, const void *)); +extern DECLSPEC void SDLCALL SDL_qsort(void *base, size_t nmemb, size_t size, int (SDLCALL *compare) (const void *, const void *)); +extern DECLSPEC void * SDLCALL SDL_bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (SDLCALL *compare) (const void *, const void *)); extern DECLSPEC int SDLCALL SDL_abs(int x); @@ -727,6 +734,65 @@ SDL_FORCE_INLINE void *SDL_memcpy4(SDL_OUT_BYTECAP(dwords*4) void *dst, SDL_IN_B return SDL_memcpy(dst, src, dwords * 4); } +/** + * If a * b would overflow, return -1. Otherwise store a * b via ret + * and return 0. + * + * \since This function is available since SDL 2.24.0. + */ +SDL_FORCE_INLINE int SDL_size_mul_overflow (size_t a, + size_t b, + size_t *ret) +{ + if (a != 0 && b > SDL_SIZE_MAX / a) { + return -1; + } + *ret = a * b; + return 0; +} + +#if _SDL_HAS_BUILTIN(__builtin_mul_overflow) +/* This needs to be wrapped in an inline rather than being a direct #define, + * because __builtin_mul_overflow() is type-generic, but we want to be + * consistent about interpreting a and b as size_t. */ +SDL_FORCE_INLINE int _SDL_size_mul_overflow_builtin (size_t a, + size_t b, + size_t *ret) +{ + return __builtin_mul_overflow(a, b, ret) == 0 ? 0 : -1; +} +#define SDL_size_mul_overflow(a, b, ret) (_SDL_size_mul_overflow_builtin(a, b, ret)) +#endif + +/** + * If a + b would overflow, return -1. Otherwise store a + b via ret + * and return 0. + * + * \since This function is available since SDL 2.24.0. + */ +SDL_FORCE_INLINE int SDL_size_add_overflow (size_t a, + size_t b, + size_t *ret) +{ + if (b > SDL_SIZE_MAX - a) { + return -1; + } + *ret = a + b; + return 0; +} + +#if _SDL_HAS_BUILTIN(__builtin_add_overflow) +/* This needs to be wrapped in an inline rather than being a direct #define, + * the same as the call to __builtin_mul_overflow() above. */ +SDL_FORCE_INLINE int _SDL_size_add_overflow_builtin (size_t a, + size_t b, + size_t *ret) +{ + return __builtin_add_overflow(a, b, ret) == 0 ? 0 : -1; +} +#define SDL_size_add_overflow(a, b, ret) (_SDL_size_add_overflow_builtin(a, b, ret)) +#endif + /* Ends C function definitions when using C++ */ #ifdef __cplusplus } diff --git a/include/SDL_system.h b/include/SDL_system.h index 41563add4..c540e4748 100644 --- a/include/SDL_system.h +++ b/include/SDL_system.h @@ -195,7 +195,7 @@ extern DECLSPEC int SDLCALL SDL_LinuxSetThreadPriorityAndPolicy(Sint64 threadID, * * \sa SDL_iPhoneSetEventPump */ -extern DECLSPEC int SDLCALL SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam); +extern DECLSPEC int SDLCALL SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (SDLCALL *callback)(void*), void *callbackParam); #define SDL_iOSSetEventPump(enabled) SDL_iPhoneSetEventPump(enabled) diff --git a/include/SDL_thread.h b/include/SDL_thread.h index 35e680ddf..1e04a4f8f 100644 --- a/include/SDL_thread.h +++ b/include/SDL_thread.h @@ -129,7 +129,7 @@ SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data, pfnSDL_CurrentEndThread pfnEndThread); extern DECLSPEC SDL_Thread *SDLCALL -SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *), +SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, const char *name, const size_t stacksize, void *data, pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentEndThread pfnEndThread); diff --git a/include/SDL_version.h b/include/SDL_version.h index 3df4e041a..302e4628d 100644 --- a/include/SDL_version.h +++ b/include/SDL_version.h @@ -58,8 +58,8 @@ typedef struct SDL_version /* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL */ #define SDL_MAJOR_VERSION 2 -#define SDL_MINOR_VERSION 0 -#define SDL_PATCHLEVEL 22 +#define SDL_MINOR_VERSION 23 +#define SDL_PATCHLEVEL 0 /** * Macro to determine SDL version program was compiled against. @@ -83,6 +83,8 @@ typedef struct SDL_version (x)->patch = SDL_PATCHLEVEL; \ } +/* TODO: Remove this whole block in SDL 3 */ +#if SDL_MAJOR_VERSION < 3 /** * This macro turns the version numbers into a numeric value: * \verbatim @@ -90,21 +92,35 @@ typedef struct SDL_version \endverbatim * * This assumes that there will never be more than 100 patchlevels. + * + * In versions higher than 2.9.0, the minor version overflows into + * the thousands digit: for example, 2.23.0 is encoded as 4300, + * and 2.255.99 would be encoded as 25799. + * This macro will not be available in SDL 3.x. */ #define SDL_VERSIONNUM(X, Y, Z) \ ((X)*1000 + (Y)*100 + (Z)) /** * This is the version number macro for the current SDL version. + * + * In versions higher than 2.9.0, the minor version overflows into + * the thousands digit: for example, 2.23.0 is encoded as 4300. + * This macro will not be available in SDL 3.x. + * + * Deprecated, use SDL_VERSION_ATLEAST or SDL_VERSION instead. */ #define SDL_COMPILEDVERSION \ SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) +#endif /* SDL_MAJOR_VERSION < 3 */ /** * This macro will evaluate to true if compiled with SDL at least X.Y.Z. */ #define SDL_VERSION_ATLEAST(X, Y, Z) \ - (SDL_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z)) + ((SDL_MAJOR_VERSION >= X) && \ + (SDL_MAJOR_VERSION > X || SDL_MINOR_VERSION >= Y) && \ + (SDL_MAJOR_VERSION > X || SDL_MINOR_VERSION > Y || SDL_PATCHLEVEL >= Z)) /** * Get the version of SDL that is linked against your program. diff --git a/src/SDL.c b/src/SDL.c index 68a4f5da2..a65d9c519 100644 --- a/src/SDL.c +++ b/src/SDL.c @@ -47,6 +47,7 @@ #include "SDL_bits.h" #include "SDL_revision.h" #include "SDL_assert_c.h" +#include "SDL_log_c.h" #include "events/SDL_events_c.h" #include "haptic/SDL_haptic_c.h" #include "joystick/SDL_joystick_c.h" @@ -61,6 +62,26 @@ extern int SDL_HelperWindowCreate(void); extern int SDL_HelperWindowDestroy(void); #endif +#ifdef SDL_BUILD_MAJOR_VERSION +SDL_COMPILE_TIME_ASSERT(SDL_BUILD_MAJOR_VERSION, + SDL_MAJOR_VERSION == SDL_BUILD_MAJOR_VERSION); +SDL_COMPILE_TIME_ASSERT(SDL_BUILD_MINOR_VERSION, + SDL_MINOR_VERSION == SDL_BUILD_MINOR_VERSION); +SDL_COMPILE_TIME_ASSERT(SDL_BUILD_MICRO_VERSION, + SDL_PATCHLEVEL == SDL_BUILD_MICRO_VERSION); +#endif + +SDL_COMPILE_TIME_ASSERT(SDL_MAJOR_VERSION_min, SDL_MAJOR_VERSION >= 0); +/* Limited only by the need to fit in SDL_version */ +SDL_COMPILE_TIME_ASSERT(SDL_MAJOR_VERSION_max, SDL_MAJOR_VERSION <= 255); + +SDL_COMPILE_TIME_ASSERT(SDL_MINOR_VERSION_min, SDL_MINOR_VERSION >= 0); +/* Limited only by the need to fit in SDL_version */ +SDL_COMPILE_TIME_ASSERT(SDL_MINOR_VERSION_max, SDL_MINOR_VERSION <= 255); + +SDL_COMPILE_TIME_ASSERT(SDL_PATCHLEVEL_min, SDL_PATCHLEVEL >= 0); +/* Limited by its encoding in SDL_VERSIONNUM and in the ABI versions */ +SDL_COMPILE_TIME_ASSERT(SDL_PATCHLEVEL_max, SDL_PATCHLEVEL <= 99); /* This is not declared in any header, although it is shared between some parts of SDL, because we don't want anything calling it without an @@ -156,6 +177,8 @@ SDL_InitSubSystem(Uint32 flags) return SDL_SetError("Application didn't initialize properly, did you include SDL_main.h in the file containing your main() function?"); } + SDL_LogInit(); + /* Clear the error message */ SDL_ClearError(); @@ -470,12 +493,13 @@ SDL_Quit(void) SDL_ClearHints(); SDL_AssertionsQuit(); - SDL_LogResetPriorities(); #if SDL_USE_LIBDBUS SDL_DBus_Quit(); #endif + SDL_LogQuit(); + /* Now that every subsystem has been quit, we reset the subsystem refcount * and the list of initialized subsystems. */ @@ -563,6 +587,8 @@ SDL_GetPlatform(void) return "PlayStation Portable"; #elif __VITA__ return "PlayStation Vita"; +#elif __NGAGE__ + return "Nokia N-Gage"; #else return "Unknown (see SDL_platform.h)"; #endif diff --git a/src/SDL_assert.c b/src/SDL_assert.c index 9c7acac55..02cd6b3fd 100644 --- a/src/SDL_assert.c +++ b/src/SDL_assert.c @@ -45,6 +45,8 @@ #include #endif +/* The size of the stack buffer to use for rendering assert messages. */ +#define SDL_MAX_ASSERT_MESSAGE_STACK 256 static SDL_assert_state SDLCALL SDL_PromptAssertion(const SDL_assert_data *data, void *userdata); @@ -88,6 +90,20 @@ static void SDL_AddAssertionToReport(SDL_assert_data *data) } } +#ifdef __WIN32__ + #define ENDLINE "\r\n" +#else + #define ENDLINE "\n" +#endif + +static int SDL_RenderAssertMessage(char *buf, size_t buf_len, const SDL_assert_data *data) { + return SDL_snprintf(buf, buf_len, + "Assertion failure at %s (%s:%d), triggered %u %s:" ENDLINE " '%s'", + data->function, data->filename, data->linenum, + data->trigger_count, (data->trigger_count == 1) ? "time" : "times", + data->condition + ); +} static void SDL_GenerateAssertionReport(void) { @@ -137,16 +153,9 @@ static SDL_NORETURN void SDL_AbortAssertion(void) SDL_ExitProcess(42); } - static SDL_assert_state SDLCALL SDL_PromptAssertion(const SDL_assert_data *data, void *userdata) { -#ifdef __WIN32__ - #define ENDLINE "\r\n" -#else - #define ENDLINE "\n" -#endif - const char *envr; SDL_assert_state state = SDL_ASSERTION_ABORT; SDL_Window *window; @@ -160,30 +169,46 @@ SDL_PromptAssertion(const SDL_assert_data *data, void *userdata) { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, SDL_ASSERTION_ALWAYS_IGNORE, "Always Ignore" } }; - char *message; int selected; + char stack_buf[SDL_MAX_ASSERT_MESSAGE_STACK]; + char *message = stack_buf; + size_t buf_len = sizeof(stack_buf); + int len; + (void) userdata; /* unused in default handler. */ - /* !!! FIXME: why is this using SDL_stack_alloc and not just "char message[SDL_MAX_LOG_MESSAGE];" ? */ - message = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE); - if (!message) { - /* Uh oh, we're in real trouble now... */ + /* Assume the output will fit... */ + len = SDL_RenderAssertMessage(message, buf_len, data); + + /* .. and if it didn't, try to allocate as much room as we actually need. */ + if (len >= (int)buf_len) { + if (SDL_size_add_overflow(len, 1, &buf_len) == 0) { + message = (char *)SDL_malloc(buf_len); + if (message) { + len = SDL_RenderAssertMessage(message, buf_len, data); + } else { + message = stack_buf; + } + } + } + + /* Something went very wrong */ + if (len < 0) { + if (message != stack_buf) { + SDL_free(message); + } return SDL_ASSERTION_ABORT; } - SDL_snprintf(message, SDL_MAX_LOG_MESSAGE, - "Assertion failure at %s (%s:%d), triggered %u %s:" ENDLINE - " '%s'", - data->function, data->filename, data->linenum, - data->trigger_count, (data->trigger_count == 1) ? "time" : "times", - data->condition); debug_print("\n\n%s\n\n", message); /* let env. variable override, so unit tests won't block in a GUI. */ envr = SDL_getenv("SDL_ASSERT"); if (envr != NULL) { - SDL_stack_free(message); + if (message != stack_buf) { + SDL_free(message); + } if (SDL_strcmp(envr, "abort") == 0) { return SDL_ASSERTION_ABORT; @@ -301,7 +326,9 @@ SDL_PromptAssertion(const SDL_assert_data *data, void *userdata) SDL_RestoreWindow(window); } - SDL_stack_free(message); + if (message != stack_buf) { + SDL_free(message); + } return state; } diff --git a/src/SDL_internal.h b/src/SDL_internal.h index 69da271c6..43e407f87 100644 --- a/src/SDL_internal.h +++ b/src/SDL_internal.h @@ -43,10 +43,9 @@ #if SDL_DYNAMIC_API #include "dynapi/SDL_dynapi_overrides.h" -/* force DECLSPEC and SDLCALL off...it's all internal symbols now. +/* force DECLSPEC off...it's all internal symbols now. These will have actual #defines during SDL_dynapi.c only */ #define DECLSPEC -#define SDLCALL #endif #include "SDL_config.h" diff --git a/src/SDL_log.c b/src/SDL_log.c index 4f820ffa7..49027e47b 100644 --- a/src/SDL_log.c +++ b/src/SDL_log.c @@ -28,6 +28,8 @@ #include "SDL_error.h" #include "SDL_log.h" +#include "SDL_mutex.h" +#include "SDL_log_c.h" #if HAVE_STDIO_H #include @@ -37,6 +39,12 @@ #include #endif +#include "stdlib/SDL_vacopy.h" + + +/* The size of the stack buffer to use for rendering log messages. */ +#define SDL_MAX_LOG_MESSAGE_STACK 256 + #define DEFAULT_PRIORITY SDL_LOG_PRIORITY_CRITICAL #define DEFAULT_ASSERT_PRIORITY SDL_LOG_PRIORITY_WARN #define DEFAULT_APPLICATION_PRIORITY SDL_LOG_PRIORITY_INFO @@ -59,6 +67,7 @@ static SDL_LogPriority SDL_application_priority = DEFAULT_APPLICATION_PRIORITY; static SDL_LogPriority SDL_test_priority = DEFAULT_TEST_PRIORITY; static SDL_LogOutputFunction SDL_log_function = SDL_LogOutput; static void *SDL_log_userdata = NULL; +static SDL_mutex *log_function_mutex = NULL; static const char *SDL_priority_prefixes[SDL_NUM_LOG_PRIORITIES] = { NULL, @@ -92,6 +101,24 @@ static int SDL_android_priority[SDL_NUM_LOG_PRIORITIES] = { }; #endif /* __ANDROID__ */ +void +SDL_LogInit(void) +{ + if (!log_function_mutex) { + /* if this fails we'll try to continue without it. */ + log_function_mutex = SDL_CreateMutex(); + } +} + +void +SDL_LogQuit(void) +{ + SDL_LogResetPriorities(); + if (log_function_mutex) { + SDL_DestroyMutex(log_function_mutex); + log_function_mutex = NULL; + } +} void SDL_LogSetAllPriority(SDL_LogPriority priority) @@ -264,8 +291,11 @@ GetCategoryPrefix(int category) void SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va_list ap) { - char *message; - size_t len; + char *message = NULL; + char stack_buf[SDL_MAX_LOG_MESSAGE_STACK]; + size_t len_plus_term; + int len; + va_list aq; /* Nothing to do if we don't have an output function */ if (!SDL_log_function) { @@ -282,16 +312,33 @@ SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va_list return; } - /* !!! FIXME: why not just "char message[SDL_MAX_LOG_MESSAGE];" ? */ - message = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE); - if (!message) { - return; + if (!log_function_mutex) { + /* this mutex creation can race if you log from two threads at startup. You should have called SDL_Init first! */ + log_function_mutex = SDL_CreateMutex(); } - SDL_vsnprintf(message, SDL_MAX_LOG_MESSAGE, fmt, ap); + /* Render into stack buffer */ + va_copy(aq, ap); + len = SDL_vsnprintf(stack_buf, sizeof(stack_buf), fmt, aq); + va_end(aq); + + if (len < 0) + return; + + /* If message truncated, allocate and re-render */ + if (len >= sizeof(stack_buf) && SDL_size_add_overflow(len, 1, &len_plus_term) == 0) { + /* Allocate exactly what we need, including the zero-terminator */ + message = (char *)SDL_malloc(len_plus_term); + if (!message) + return; + va_copy(aq, ap); + len = SDL_vsnprintf(message, len_plus_term, fmt, aq); + va_end(aq); + } else { + message = stack_buf; + } /* Chop off final endline. */ - len = SDL_strlen(message); if ((len > 0) && (message[len-1] == '\n')) { message[--len] = '\0'; if ((len > 0) && (message[len-1] == '\r')) { /* catch "\r\n", too. */ @@ -299,8 +346,20 @@ SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va_list } } + if (log_function_mutex) { + SDL_LockMutex(log_function_mutex); + } + SDL_log_function(SDL_log_userdata, category, priority, message); - SDL_stack_free(message); + + if (log_function_mutex) { + SDL_UnlockMutex(log_function_mutex); + } + + /* Free only if dynamically allocated */ + if (message != stack_buf) { + SDL_free(message); + } } #if defined(__WIN32__) && !defined(HAVE_STDIO_H) && !defined(__WINRT__) @@ -403,17 +462,10 @@ SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority, #elif defined(__APPLE__) && (defined(SDL_VIDEO_DRIVER_COCOA) || defined(SDL_VIDEO_DRIVER_UIKIT)) /* Technically we don't need Cocoa/UIKit, but that's where this function is defined for now. */ - extern void SDL_NSLog(const char *text); + extern void SDL_NSLog(const char *prefix, const char *text); { - char *text; - /* !!! FIXME: why not just "char text[SDL_MAX_LOG_MESSAGE];" ? */ - text = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE); - if (text) { - SDL_snprintf(text, SDL_MAX_LOG_MESSAGE, "%s: %s", SDL_priority_prefixes[priority], message); - SDL_NSLog(text); - SDL_stack_free(text); - return; - } + SDL_NSLog(SDL_priority_prefixes[priority], message); + return; } #elif defined(__PSP__) { diff --git a/src/SDL_log_c.h b/src/SDL_log_c.h new file mode 100644 index 000000000..4716b7ada --- /dev/null +++ b/src/SDL_log_c.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + 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" + +/* This file defines useful function for working with SDL logging */ + +#ifndef SDL_log_c_h_ +#define SDL_log_c_h_ + +extern void SDL_LogInit(void); +extern void SDL_LogQuit(void); + +#endif /* SDL_log_c_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index fe8063e82..aef25a086 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -1652,8 +1652,6 @@ SDL_AudioQuit(void) #ifdef HAVE_LIBSAMPLERATE_H UnloadLibSampleRate(); #endif - - SDL_FreeResampleFilter(); } #define NUM_FORMATS 10 diff --git a/src/audio/SDL_audio_c.h b/src/audio/SDL_audio_c.h index cddaecef0..bfa0760de 100644 --- a/src/audio/SDL_audio_c.h +++ b/src/audio/SDL_audio_c.h @@ -70,11 +70,6 @@ extern SDL_AudioFilter SDL_Convert_F32_to_S16; extern SDL_AudioFilter SDL_Convert_F32_to_U16; extern SDL_AudioFilter SDL_Convert_F32_to_S32; -/* You need to call SDL_PrepareResampleFilter() before using the internal resampler. - SDL_AudioQuit() calls SDL_FreeResamplerFilter(), you should never call it yourself. */ -extern int SDL_PrepareResampleFilter(void); -extern void SDL_FreeResampleFilter(void); - #endif /* SDL_audio_c_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/audio/SDL_audio_resampler_filter.h b/src/audio/SDL_audio_resampler_filter.h new file mode 100644 index 000000000..9b4728c3b --- /dev/null +++ b/src/audio/SDL_audio_resampler_filter.h @@ -0,0 +1,1062 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + 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. +*/ + +/* DO NOT EDIT, THIS FILE WAS GENERATED BY build-scripts/gen_audio_resampler_filter.c */ + +#define RESAMPLER_ZERO_CROSSINGS 5 +#define RESAMPLER_BITS_PER_SAMPLE 16 +#define RESAMPLER_SAMPLES_PER_ZERO_CROSSING (1 << ((RESAMPLER_BITS_PER_SAMPLE / 2) + 1)) +#define RESAMPLER_FILTER_SIZE ((RESAMPLER_SAMPLES_PER_ZERO_CROSSING * RESAMPLER_ZERO_CROSSINGS) + 1) + +static const float ResamplerFilter[RESAMPLER_FILTER_SIZE] = { + 1.000000000f, 0.999993682f, 0.999974370f, 0.999941289f, 0.999894559f, + 0.999834180f, 0.999760151f, 0.999672413f, 0.999571025f, 0.999455988f, + 0.999327302f, 0.999184966f, 0.999028981f, 0.998859286f, 0.998676121f, + 0.998479128f, 0.998268604f, 0.998044431f, 0.997806668f, 0.997555375f, + 0.997290313f, 0.997011721f, 0.996719599f, 0.996413827f, 0.996094406f, + 0.995761573f, 0.995415151f, 0.995055199f, 0.994681656f, 0.994294584f, + 0.993894041f, 0.993480027f, 0.993052363f, 0.992611289f, 0.992156804f, + 0.991688788f, 0.991207361f, 0.990712583f, 0.990204275f, 0.989682615f, + 0.989147604f, 0.988599122f, 0.988037288f, 0.987462223f, 0.986873686f, + 0.986271918f, 0.985656738f, 0.985028386f, 0.984386861f, 0.983731806f, + 0.983063757f, 0.982382476f, 0.981687963f, 0.980980217f, 0.980259418f, + 0.979525447f, 0.978778243f, 0.978018105f, 0.977244914f, 0.976458490f, + 0.975659251f, 0.974846840f, 0.974021494f, 0.973183155f, 0.972331941f, + 0.971467674f, 0.970590651f, 0.969700634f, 0.968797863f, 0.967882276f, + 0.966953754f, 0.966012537f, 0.965058565f, 0.964091897f, 0.963112533f, + 0.962120414f, 0.961115718f, 0.960098326f, 0.959068418f, 0.958025992f, + 0.956970990f, 0.955903471f, 0.954823375f, 0.953730941f, 0.952626109f, + 0.951508820f, 0.950379193f, 0.949237227f, 0.948082924f, 0.946916521f, + 0.945737660f, 0.944546640f, 0.943343520f, 0.942128360f, 0.940900803f, + 0.939661384f, 0.938409984f, 0.937146366f, 0.935870886f, 0.934583426f, + 0.933284163f, 0.931972861f, 0.930649877f, 0.929314911f, 0.927968264f, + 0.926609993f, 0.925239921f, 0.923858225f, 0.922464967f, 0.921060085f, + 0.919643581f, 0.918215632f, 0.916776240f, 0.915325403f, 0.913863063f, + 0.912389517f, 0.910904646f, 0.909408391f, 0.907901049f, 0.906382322f, + 0.904852629f, 0.903311789f, 0.901759744f, 0.900196850f, 0.898622811f, + 0.897037864f, 0.895442069f, 0.893835366f, 0.892217875f, 0.890589595f, + 0.888950586f, 0.887300909f, 0.885640502f, 0.883969545f, 0.882288039f, + 0.880595982f, 0.878893554f, 0.877180517f, 0.875457227f, 0.873723626f, + 0.871979713f, 0.870225549f, 0.868461132f, 0.866686642f, 0.864902079f, + 0.863107383f, 0.861302733f, 0.859488070f, 0.857663572f, 0.855829120f, + 0.853984952f, 0.852130949f, 0.850267172f, 0.848393857f, 0.846510828f, + 0.844618261f, 0.842716157f, 0.840804636f, 0.838883698f, 0.836953342f, + 0.835013688f, 0.833064795f, 0.831106603f, 0.829139292f, 0.827162862f, + 0.825177312f, 0.823182821f, 0.821179330f, 0.819167018f, 0.817145705f, + 0.815115690f, 0.813076973f, 0.811029494f, 0.808973312f, 0.806908667f, + 0.804835379f, 0.802753687f, 0.800663531f, 0.798565030f, 0.796458125f, + 0.794343054f, 0.792219698f, 0.790088236f, 0.787948668f, 0.785801113f, + 0.783645451f, 0.781481922f, 0.779310465f, 0.777131259f, 0.774944246f, + 0.772749543f, 0.770547271f, 0.768337309f, 0.766119778f, 0.763894856f, + 0.761662483f, 0.759422719f, 0.757175624f, 0.754921377f, 0.752659857f, + 0.750391185f, 0.748115480f, 0.745832801f, 0.743543088f, 0.741246462f, + 0.738943100f, 0.736632884f, 0.734315932f, 0.731992364f, 0.729662120f, + 0.727325320f, 0.724982083f, 0.722632408f, 0.720276356f, 0.717914045f, + 0.715545416f, 0.713170588f, 0.710789680f, 0.708402693f, 0.706009746f, + 0.703610778f, 0.701205969f, 0.698795319f, 0.696378946f, 0.693956852f, + 0.691529095f, 0.689095736f, 0.686656833f, 0.684212506f, 0.681762815f, + 0.679307759f, 0.676847458f, 0.674381971f, 0.671911240f, 0.669435501f, + 0.666954637f, 0.664468944f, 0.661978245f, 0.659482718f, 0.656982541f, + 0.654477477f, 0.651967824f, 0.649453580f, 0.646934807f, 0.644411504f, + 0.641883910f, 0.639351964f, 0.636815608f, 0.634275198f, 0.631730616f, + 0.629181862f, 0.626629114f, 0.624072373f, 0.621511757f, 0.618947387f, + 0.616379082f, 0.613807201f, 0.611231565f, 0.608652413f, 0.606069744f, + 0.603483617f, 0.600894034f, 0.598301172f, 0.595705032f, 0.593105674f, + 0.590503156f, 0.587897599f, 0.585289061f, 0.582677484f, 0.580063045f, + 0.577445805f, 0.574825764f, 0.572203040f, 0.569577694f, 0.566949785f, + 0.564319372f, 0.561686456f, 0.559051216f, 0.556413651f, 0.553773820f, + 0.551131785f, 0.548487663f, 0.545841396f, 0.543193221f, 0.540543079f, + 0.537890971f, 0.535237134f, 0.532581568f, 0.529924273f, 0.527265370f, + 0.524604917f, 0.521942914f, 0.519279540f, 0.516614795f, 0.513948679f, + 0.511281490f, 0.508612931f, 0.505943298f, 0.503272593f, 0.500600994f, + 0.497928351f, 0.495254934f, 0.492580622f, 0.489905566f, 0.487229884f, + 0.484553576f, 0.481876701f, 0.479199320f, 0.476521552f, 0.473843396f, + 0.471164882f, 0.468486160f, 0.465807229f, 0.463128209f, 0.460449100f, + 0.457770079f, 0.455091029f, 0.452412128f, 0.449733406f, 0.447054923f, + 0.444376737f, 0.441698909f, 0.439021617f, 0.436344713f, 0.433668375f, + 0.430992693f, 0.428317666f, 0.425643355f, 0.422969848f, 0.420297176f, + 0.417625397f, 0.414954633f, 0.412284881f, 0.409616232f, 0.406948745f, + 0.404282451f, 0.401617438f, 0.398953736f, 0.396291435f, 0.393630594f, + 0.390971363f, 0.388313591f, 0.385657459f, 0.383003026f, 0.380350292f, + 0.377699375f, 0.375050306f, 0.372403204f, 0.369758040f, 0.367114902f, + 0.364473879f, 0.361834973f, 0.359198302f, 0.356563985f, 0.353931844f, + 0.351302117f, 0.348674864f, 0.346050024f, 0.343427807f, 0.340808123f, + 0.338191152f, 0.335576862f, 0.332965344f, 0.330356658f, 0.327750862f, + 0.325147986f, 0.322548091f, 0.319951355f, 0.317357630f, 0.314767033f, + 0.312179655f, 0.309595555f, 0.307014734f, 0.304437339f, 0.301863313f, + 0.299292803f, 0.296725839f, 0.294162393f, 0.291602641f, 0.289046586f, + 0.286494225f, 0.283945769f, 0.281401068f, 0.278860301f, 0.276323408f, + 0.273790598f, 0.271261781f, 0.268737078f, 0.266216546f, 0.263700217f, + 0.261188149f, 0.258680373f, 0.256176978f, 0.253677934f, 0.251183391f, + 0.248693451f, 0.246207923f, 0.243727028f, 0.241250798f, 0.238779247f, + 0.236312449f, 0.233850464f, 0.231393293f, 0.228941023f, 0.226493701f, + 0.224051371f, 0.221614078f, 0.219181836f, 0.216754735f, 0.214332923f, + 0.211916193f, 0.209504753f, 0.207098618f, 0.204697832f, 0.202302471f, + 0.199912533f, 0.197528124f, 0.195149198f, 0.192775860f, 0.190408155f, + 0.188046113f, 0.185689807f, 0.183339253f, 0.180994540f, 0.178655609f, + 0.176322535f, 0.173995405f, 0.171674222f, 0.169359058f, 0.167049929f, + 0.164746925f, 0.162450001f, 0.160159275f, 0.157874763f, 0.155596510f, + 0.153324530f, 0.151058972f, 0.148799688f, 0.146546826f, 0.144300416f, + 0.142060474f, 0.139827073f, 0.137600228f, 0.135380000f, 0.133166388f, + 0.130959451f, 0.128759250f, 0.126565769f, 0.124379098f, 0.122199245f, + 0.120026320f, 0.117860198f, 0.115701027f, 0.113548823f, 0.111403592f, + 0.109265402f, 0.107134290f, 0.105010264f, 0.102893390f, 0.100783676f, + 0.098681159f, 0.096585885f, 0.094497882f, 0.092417173f, 0.090343870f, + 0.088277847f, 0.086219221f, 0.084168032f, 0.082124293f, 0.080088042f, + 0.078059308f, 0.076038122f, 0.074024513f, 0.072018512f, 0.070020139f, + 0.068029441f, 0.066046432f, 0.064071149f, 0.062103685f, 0.060143925f, + 0.058191977f, 0.056247860f, 0.054311592f, 0.052383222f, 0.050462760f, + 0.048550237f, 0.046645675f, 0.044749107f, 0.042860553f, 0.040980037f, + 0.039107583f, 0.037243221f, 0.035387039f, 0.033538923f, 0.031698968f, + 0.029867193f, 0.028043624f, 0.026228283f, 0.024421191f, 0.022622371f, + 0.020831848f, 0.019049639f, 0.017275762f, 0.015510243f, 0.013753103f, + 0.012004361f, 0.010264101f, 0.008532210f, 0.006808777f, 0.005093819f, + 0.003387353f, 0.001689399f, -0.000000024f, -0.001680900f, -0.003353210f, + -0.005016938f, -0.006672067f, -0.008318579f, -0.009956459f, -0.011585629f, + -0.013206195f, -0.014818084f, -0.016421281f, -0.018015765f, -0.019601526f, + -0.021178551f, -0.022746822f, -0.024306327f, -0.025857056f, -0.027398987f, + -0.028932119f, -0.030456433f, -0.031971917f, -0.033478502f, -0.034976289f, + -0.036465216f, -0.037945267f, -0.039416436f, -0.040878706f, -0.042332072f, + -0.043776520f, -0.045212042f, -0.046638630f, -0.048056271f, -0.049464963f, + -0.050864697f, -0.052255459f, -0.053637192f, -0.055009995f, -0.056373812f, + -0.057728622f, -0.059074435f, -0.060411237f, -0.061739020f, -0.063057788f, + -0.064367518f, -0.065668218f, -0.066959888f, -0.068242513f, -0.069516085f, + -0.070780613f, -0.072036028f, -0.073282443f, -0.074519798f, -0.075748093f, + -0.076967306f, -0.078177467f, -0.079378553f, -0.080570564f, -0.081753515f, + -0.082927369f, -0.084092163f, -0.085247882f, -0.086394526f, -0.087532081f, + -0.088660523f, -0.089779936f, -0.090890266f, -0.091991536f, -0.093083732f, + -0.094166860f, -0.095240898f, -0.096305899f, -0.097361818f, -0.098408684f, + -0.099446490f, -0.100475237f, -0.101494931f, -0.102505587f, -0.103507154f, + -0.104499720f, -0.105483264f, -0.106457770f, -0.107423261f, -0.108379729f, + -0.109327182f, -0.110265635f, -0.111195073f, -0.112115517f, -0.113026999f, + -0.113929473f, -0.114823014f, -0.115707509f, -0.116583094f, -0.117449738f, + -0.118307441f, -0.119156219f, -0.119996056f, -0.120826989f, -0.121649019f, + -0.122462146f, -0.123266406f, -0.124061778f, -0.124848284f, -0.125625938f, + -0.126394749f, -0.127154693f, -0.127905846f, -0.128648207f, -0.129381746f, + -0.130106509f, -0.130822510f, -0.131529734f, -0.132228225f, -0.132917970f, + -0.133599013f, -0.134271339f, -0.134934962f, -0.135589913f, -0.136236191f, + -0.136873797f, -0.137502789f, -0.138123170f, -0.138734937f, -0.139338136f, + -0.139932722f, -0.140518770f, -0.141096294f, -0.141665265f, -0.142225727f, + -0.142777696f, -0.143321201f, -0.143856242f, -0.144382849f, -0.144900993f, + -0.145410761f, -0.145912141f, -0.146405146f, -0.146889821f, -0.147366136f, + -0.147834152f, -0.148293883f, -0.148745313f, -0.149188504f, -0.149623469f, + -0.150050193f, -0.150468737f, -0.150879115f, -0.151281342f, -0.151675433f, + -0.152061403f, -0.152439296f, -0.152809098f, -0.153170869f, -0.153524607f, + -0.153870359f, -0.154208109f, -0.154537901f, -0.154859766f, -0.155173704f, + -0.155479759f, -0.155777946f, -0.156068295f, -0.156350806f, -0.156625539f, + -0.156892478f, -0.157151699f, -0.157403171f, -0.157646939f, -0.157883018f, + -0.158111468f, -0.158332288f, -0.158545509f, -0.158751160f, -0.158949256f, + -0.159139827f, -0.159322888f, -0.159498483f, -0.159666643f, -0.159827381f, + -0.159980699f, -0.160126686f, -0.160265297f, -0.160396621f, -0.160520658f, + -0.160637438f, -0.160746962f, -0.160849288f, -0.160944447f, -0.161032468f, + -0.161113337f, -0.161187142f, -0.161253884f, -0.161313564f, -0.161366254f, + -0.161411941f, -0.161450699f, -0.161482543f, -0.161507472f, -0.161525562f, + -0.161536828f, -0.161541268f, -0.161538944f, -0.161529869f, -0.161514089f, + -0.161491618f, -0.161462501f, -0.161426738f, -0.161384419f, -0.161335513f, + -0.161280081f, -0.161218151f, -0.161149755f, -0.161074907f, -0.160993651f, + -0.160906032f, -0.160812065f, -0.160711765f, -0.160605207f, -0.160492390f, + -0.160373345f, -0.160248131f, -0.160116762f, -0.159979254f, -0.159835666f, + -0.159686014f, -0.159530357f, -0.159368694f, -0.159201056f, -0.159027517f, + -0.158848062f, -0.158662766f, -0.158471599f, -0.158274680f, -0.158071980f, + -0.157863557f, -0.157649443f, -0.157429650f, -0.157204241f, -0.156973228f, + -0.156736642f, -0.156494558f, -0.156246960f, -0.155993909f, -0.155735433f, + -0.155471563f, -0.155202329f, -0.154927775f, -0.154647917f, -0.154362813f, + -0.154072478f, -0.153776988f, -0.153476328f, -0.153170541f, -0.152859688f, + -0.152543753f, -0.152222827f, -0.151896924f, -0.151566073f, -0.151230305f, + -0.150889665f, -0.150544196f, -0.150193915f, -0.149838865f, -0.149479061f, + -0.149114594f, -0.148745432f, -0.148371637f, -0.147993281f, -0.147610337f, + -0.147222877f, -0.146830946f, -0.146434546f, -0.146033719f, -0.145628527f, + -0.145218968f, -0.144805118f, -0.144386992f, -0.143964618f, -0.143538073f, + -0.143107325f, -0.142672464f, -0.142233476f, -0.141790435f, -0.141343385f, + -0.140892327f, -0.140437320f, -0.139978394f, -0.139515579f, -0.139048934f, + -0.138578460f, -0.138104215f, -0.137626216f, -0.137144551f, -0.136659175f, + -0.136170194f, -0.135677606f, -0.135181442f, -0.134681761f, -0.134178594f, + -0.133671984f, -0.133161947f, -0.132648528f, -0.132131740f, -0.131611660f, + -0.131088302f, -0.130561695f, -0.130031943f, -0.129498973f, -0.128962860f, + -0.128423676f, -0.127881393f, -0.127336115f, -0.126787826f, -0.126236603f, + -0.125682443f, -0.125125393f, -0.124565504f, -0.124002807f, -0.123437323f, + -0.122869089f, -0.122298159f, -0.121724561f, -0.121148311f, -0.120569460f, + -0.119988061f, -0.119404130f, -0.118817687f, -0.118228793f, -0.117637470f, + -0.117043748f, -0.116447672f, -0.115849286f, -0.115248613f, -0.114645667f, + -0.114040568f, -0.113433234f, -0.112823755f, -0.112212166f, -0.111598492f, + -0.110982776f, -0.110365056f, -0.109745361f, -0.109123722f, -0.108500175f, + -0.107874751f, -0.107247494f, -0.106618427f, -0.105987601f, -0.105355024f, + -0.104720749f, -0.104084812f, -0.103447236f, -0.102808066f, -0.102167316f, + -0.101525046f, -0.100881256f, -0.100236014f, -0.099589340f, -0.098941252f, + -0.098291807f, -0.097641021f, -0.096988983f, -0.096335620f, -0.095681041f, + -0.095025249f, -0.094368286f, -0.093710184f, -0.093050972f, -0.092390701f, + -0.091729380f, -0.091067046f, -0.090403758f, -0.089739501f, -0.089074343f, + -0.088408306f, -0.087741412f, -0.087073699f, -0.086405218f, -0.085735977f, + -0.085065998f, -0.084395349f, -0.083724037f, -0.083052084f, -0.082379535f, + -0.081706434f, -0.081032783f, -0.080358639f, -0.079684012f, -0.079008937f, + -0.078333504f, -0.077657640f, -0.076981425f, -0.076304883f, -0.075628042f, + -0.074950956f, -0.074273616f, -0.073596083f, -0.072918370f, -0.072240517f, + -0.071562558f, -0.070884496f, -0.070206381f, -0.069528244f, -0.068850100f, + -0.068171993f, -0.067493953f, -0.066815972f, -0.066138126f, -0.065460421f, + -0.064782880f, -0.064105548f, -0.063428439f, -0.062751584f, -0.062075011f, + -0.061398748f, -0.060722828f, -0.060047265f, -0.059372153f, -0.058697399f, + -0.058023106f, -0.057349272f, -0.056675948f, -0.056003150f, -0.055330887f, + -0.054659221f, -0.053988155f, -0.053317714f, -0.052647941f, -0.051978838f, + -0.051310450f, -0.050642796f, -0.049975898f, -0.049309790f, -0.048644483f, + -0.047980014f, -0.047316402f, -0.046653673f, -0.045991853f, -0.045330971f, + -0.044671040f, -0.044012092f, -0.043354150f, -0.042697236f, -0.042041373f, + -0.041386627f, -0.040732939f, -0.040080376f, -0.039428953f, -0.038778704f, + -0.038129643f, -0.037481792f, -0.036835186f, -0.036189832f, -0.035545766f, + -0.034902997f, -0.034261558f, -0.033621464f, -0.032982741f, -0.032345407f, + -0.031709481f, -0.031074993f, -0.030441960f, -0.029810399f, -0.029180335f, + -0.028551787f, -0.027924776f, -0.027299322f, -0.026675448f, -0.026053172f, + -0.025432510f, -0.024813488f, -0.024196124f, -0.023580479f, -0.022966485f, + -0.022354206f, -0.021743659f, -0.021134868f, -0.020527845f, -0.019922616f, + -0.019319192f, -0.018717598f, -0.018117845f, -0.017519956f, -0.016923945f, + -0.016329836f, -0.015737642f, -0.015147380f, -0.014559067f, -0.013972721f, + -0.013388360f, -0.012805998f, -0.012225654f, -0.011647343f, -0.011071082f, + -0.010496887f, -0.009924773f, -0.009354758f, -0.008786854f, -0.008221081f, + -0.007657450f, -0.007096022f, -0.006536725f, -0.005979617f, -0.005424712f, + -0.004872025f, -0.004321571f, -0.003773364f, -0.003227417f, -0.002683746f, + -0.002142363f, -0.001603282f, -0.001066516f, -0.000532080f, 0.000000015f, + 0.000529755f, 0.001057127f, 0.001582118f, 0.002104717f, 0.002624909f, + 0.003142685f, 0.003658031f, 0.004170935f, 0.004681387f, 0.005189373f, + 0.005694883f, 0.006197905f, 0.006698429f, 0.007196404f, 0.007691898f, + 0.008184860f, 0.008675281f, 0.009163151f, 0.009648458f, 0.010131192f, + 0.010611345f, 0.011088905f, 0.011563865f, 0.012036213f, 0.012505942f, + 0.012973041f, 0.013437501f, 0.013899315f, 0.014358475f, 0.014814967f, + 0.015268789f, 0.015719930f, 0.016168380f, 0.016614137f, 0.017057184f, + 0.017497523f, 0.017935142f, 0.018370032f, 0.018802188f, 0.019231608f, + 0.019658273f, 0.020082152f, 0.020503307f, 0.020921690f, 0.021337299f, + 0.021750130f, 0.022160176f, 0.022567427f, 0.022971880f, 0.023373535f, + 0.023772376f, 0.024168408f, 0.024561619f, 0.024952007f, 0.025339566f, + 0.025724288f, 0.026106175f, 0.026485221f, 0.026861422f, 0.027234772f, + 0.027605265f, 0.027972901f, 0.028337676f, 0.028699588f, 0.029058624f, + 0.029414795f, 0.029768089f, 0.030118505f, 0.030466037f, 0.030810660f, + 0.031152423f, 0.031491302f, 0.031827286f, 0.032160383f, 0.032490581f, + 0.032817882f, 0.033142287f, 0.033463787f, 0.033782389f, 0.034098089f, + 0.034410883f, 0.034720775f, 0.035027757f, 0.035331838f, 0.035633009f, + 0.035931274f, 0.036226626f, 0.036519073f, 0.036808614f, 0.037095241f, + 0.037378959f, 0.037659772f, 0.037937686f, 0.038212679f, 0.038484775f, + 0.038753960f, 0.039020218f, 0.039283592f, 0.039544068f, 0.039801639f, + 0.040056318f, 0.040308096f, 0.040556971f, 0.040802956f, 0.041046046f, + 0.041286245f, 0.041523557f, 0.041757982f, 0.041989524f, 0.042218179f, + 0.042443957f, 0.042666860f, 0.042886890f, 0.043104045f, 0.043318339f, + 0.043529764f, 0.043738328f, 0.043944035f, 0.044146888f, 0.044346895f, + 0.044544052f, 0.044738363f, 0.044929843f, 0.045118481f, 0.045304272f, + 0.045487255f, 0.045667417f, 0.045844764f, 0.046019293f, 0.046191018f, + 0.046359941f, 0.046526067f, 0.046689399f, 0.046849940f, 0.047007702f, + 0.047162689f, 0.047314901f, 0.047464348f, 0.047611035f, 0.047754966f, + 0.047896147f, 0.048034586f, 0.048170291f, 0.048303265f, 0.048433512f, + 0.048561048f, 0.048685864f, 0.048807982f, 0.048927400f, 0.049044125f, + 0.049158167f, 0.049269531f, 0.049378205f, 0.049484238f, 0.049587611f, + 0.049688339f, 0.049786422f, 0.049881872f, 0.049974691f, 0.050064899f, + 0.050152492f, 0.050237484f, 0.050319877f, 0.050399683f, 0.050476916f, + 0.050551571f, 0.050623666f, 0.050693203f, 0.050760195f, 0.050824653f, + 0.050886583f, 0.050945986f, 0.051002879f, 0.051057268f, 0.051109165f, + 0.051158577f, 0.051205512f, 0.051249981f, 0.051291991f, 0.051331542f, + 0.051368665f, 0.051403359f, 0.051435627f, 0.051465489f, 0.051492948f, + 0.051518012f, 0.051540703f, 0.051561009f, 0.051578961f, 0.051594563f, + 0.051607810f, 0.051618744f, 0.051627338f, 0.051633626f, 0.051637612f, + 0.051639307f, 0.051638719f, 0.051635865f, 0.051630747f, 0.051623378f, + 0.051613763f, 0.051601931f, 0.051587880f, 0.051571615f, 0.051553156f, + 0.051532514f, 0.051509693f, 0.051484708f, 0.051457576f, 0.051428299f, + 0.051396891f, 0.051363368f, 0.051327739f, 0.051290002f, 0.051250193f, + 0.051208302f, 0.051164351f, 0.051118344f, 0.051070303f, 0.051020239f, + 0.050968144f, 0.050914053f, 0.050857969f, 0.050799899f, 0.050739862f, + 0.050677869f, 0.050613929f, 0.050548054f, 0.050480254f, 0.050410546f, + 0.050338943f, 0.050265454f, 0.050190084f, 0.050112855f, 0.050033774f, + 0.049952857f, 0.049870111f, 0.049785554f, 0.049699202f, 0.049611051f, + 0.049521122f, 0.049429435f, 0.049335998f, 0.049240820f, 0.049143907f, + 0.049045283f, 0.048944961f, 0.048842940f, 0.048739251f, 0.048633892f, + 0.048526883f, 0.048418235f, 0.048307955f, 0.048196062f, 0.048082568f, + 0.047967490f, 0.047850832f, 0.047732603f, 0.047612831f, 0.047491513f, + 0.047368675f, 0.047244325f, 0.047118478f, 0.046991132f, 0.046862319f, + 0.046732042f, 0.046600312f, 0.046467155f, 0.046332560f, 0.046196572f, + 0.046059173f, 0.045920394f, 0.045780238f, 0.045638733f, 0.045495875f, + 0.045351684f, 0.045206167f, 0.045059349f, 0.044911236f, 0.044761848f, + 0.044611182f, 0.044459261f, 0.044306096f, 0.044151701f, 0.043996092f, + 0.043839272f, 0.043681268f, 0.043522079f, 0.043361723f, 0.043200217f, + 0.043037571f, 0.042873796f, 0.042708915f, 0.042542927f, 0.042375844f, + 0.042207699f, 0.042038482f, 0.041868217f, 0.041696910f, 0.041524585f, + 0.041351244f, 0.041176908f, 0.041001581f, 0.040825289f, 0.040648032f, + 0.040469825f, 0.040290687f, 0.040110629f, 0.039929654f, 0.039747790f, + 0.039565038f, 0.039381415f, 0.039196935f, 0.039011609f, 0.038825445f, + 0.038638465f, 0.038450673f, 0.038262092f, 0.038072724f, 0.037882581f, + 0.037691690f, 0.037500042f, 0.037307668f, 0.037114572f, 0.036920771f, + 0.036726266f, 0.036531083f, 0.036335230f, 0.036138717f, 0.035941560f, + 0.035743766f, 0.035545345f, 0.035346344f, 0.035146721f, 0.034946512f, + 0.034745730f, 0.034544386f, 0.034342494f, 0.034140065f, 0.033937111f, + 0.033733644f, 0.033529676f, 0.033325221f, 0.033120286f, 0.032914892f, + 0.032709036f, 0.032502741f, 0.032296017f, 0.032088876f, 0.031881329f, + 0.031673383f, 0.031465057f, 0.031256359f, 0.031047301f, 0.030837893f, + 0.030628148f, 0.030418083f, 0.030207697f, 0.029997014f, 0.029786035f, + 0.029574780f, 0.029363252f, 0.029151469f, 0.028939439f, 0.028727176f, + 0.028514685f, 0.028301982f, 0.028089074f, 0.027875982f, 0.027662706f, + 0.027449260f, 0.027235655f, 0.027021904f, 0.026808018f, 0.026594002f, + 0.026379872f, 0.026165638f, 0.025951311f, 0.025736896f, 0.025522409f, + 0.025307864f, 0.025093259f, 0.024878617f, 0.024663944f, 0.024449248f, + 0.024234539f, 0.024019832f, 0.023805158f, 0.023590479f, 0.023375830f, + 0.023161218f, 0.022946658f, 0.022732155f, 0.022517720f, 0.022303363f, + 0.022089096f, 0.021874927f, 0.021660868f, 0.021446921f, 0.021233102f, + 0.021019425f, 0.020805888f, 0.020592507f, 0.020379292f, 0.020166250f, + 0.019953389f, 0.019740723f, 0.019528257f, 0.019316001f, 0.019103965f, + 0.018892156f, 0.018680587f, 0.018469261f, 0.018258194f, 0.018047387f, + 0.017836852f, 0.017626595f, 0.017416634f, 0.017206967f, 0.016997607f, + 0.016788563f, 0.016579840f, 0.016371451f, 0.016163401f, 0.015955698f, + 0.015748354f, 0.015541371f, 0.015334761f, 0.015128531f, 0.014922690f, + 0.014717245f, 0.014512201f, 0.014307571f, 0.014103360f, 0.013899575f, + 0.013696224f, 0.013493315f, 0.013290856f, 0.013088853f, 0.012887316f, + 0.012686247f, 0.012485661f, 0.012285583f, 0.012085971f, 0.011886863f, + 0.011688258f, 0.011490168f, 0.011292599f, 0.011095556f, 0.010899050f, + 0.010703083f, 0.010507663f, 0.010312798f, 0.010118493f, 0.009924755f, + 0.009731592f, 0.009539006f, 0.009347008f, 0.009155600f, 0.008964794f, + 0.008774590f, 0.008584999f, 0.008396022f, 0.008207668f, 0.008019943f, + 0.007832851f, 0.007646400f, 0.007460595f, 0.007275441f, 0.007090943f, + 0.006907108f, 0.006723941f, 0.006541446f, 0.006359630f, 0.006178498f, + 0.005998055f, 0.005818305f, 0.005639255f, 0.005460909f, 0.005283272f, + 0.005106349f, 0.004930146f, 0.004754666f, 0.004579914f, 0.004405896f, + 0.004232615f, 0.004060077f, 0.003888285f, 0.003717245f, 0.003546960f, + 0.003377435f, 0.003208674f, 0.003040682f, 0.002873462f, 0.002707019f, + 0.002541356f, 0.002376478f, 0.002212389f, 0.002049116f, 0.001886615f, + 0.001724914f, 0.001564016f, 0.001403926f, 0.001244646f, 0.001086180f, + 0.000928532f, 0.000771705f, 0.000615702f, 0.000460527f, 0.000306183f, + 0.000152673f, -0.000000001f, -0.000151834f, -0.000302824f, -0.000452968f, + -0.000602263f, -0.000750707f, -0.000898296f, -0.001045028f, -0.001190900f, + -0.001335910f, -0.001480055f, -0.001623332f, -0.001765741f, -0.001907276f, + -0.002047938f, -0.002187723f, -0.002326628f, -0.002464653f, -0.002601795f, + -0.002738052f, -0.002873422f, -0.003007903f, -0.003141493f, -0.003274190f, + -0.003405993f, -0.003536900f, -0.003666909f, -0.003796018f, -0.003924227f, + -0.004051533f, -0.004177936f, -0.004303433f, -0.004428024f, -0.004551707f, + -0.004674482f, -0.004796346f, -0.004917298f, -0.005037338f, -0.005156465f, + -0.005274678f, -0.005391975f, -0.005508356f, -0.005623801f, -0.005738347f, + -0.005851975f, -0.005964684f, -0.006076474f, -0.006187343f, -0.006297291f, + -0.006406318f, -0.006514424f, -0.006621608f, -0.006727869f, -0.006833209f, + -0.006937624f, -0.007041118f, -0.007143687f, -0.007245334f, -0.007346058f, + -0.007445859f, -0.007544736f, -0.007642691f, -0.007739722f, -0.007835831f, + -0.007931018f, -0.008025283f, -0.008118626f, -0.008211047f, -0.008302549f, + -0.008393129f, -0.008482790f, -0.008571531f, -0.008659353f, -0.008746257f, + -0.008832245f, -0.008917316f, -0.009001471f, -0.009084711f, -0.009167036f, + -0.009248449f, -0.009328948f, -0.009408538f, -0.009487216f, -0.009564986f, + -0.009641849f, -0.009717803f, -0.009792852f, -0.009866998f, -0.009940239f, + -0.010012579f, -0.010084019f, -0.010154560f, -0.010224204f, -0.010292951f, + -0.010360803f, -0.010427763f, -0.010493831f, -0.010558996f, -0.010623286f, + -0.010686691f, -0.010749210f, -0.010810846f, -0.010871602f, -0.010931478f, + -0.010990476f, -0.011048601f, -0.011105850f, -0.011162230f, -0.011217739f, + -0.011272381f, -0.011326157f, -0.011379071f, -0.011431124f, -0.011482318f, + -0.011532655f, -0.011582140f, -0.011630770f, -0.011678550f, -0.011725485f, + -0.011771576f, -0.011816822f, -0.011861229f, -0.011904799f, -0.011947533f, + -0.011989436f, -0.012030509f, -0.012070752f, -0.012110173f, -0.012148771f, + -0.012186551f, -0.012223513f, -0.012259661f, -0.012295000f, -0.012329529f, + -0.012363252f, -0.012396174f, -0.012428297f, -0.012459621f, -0.012490152f, + -0.012519893f, -0.012548844f, -0.012577013f, -0.012604399f, -0.012631006f, + -0.012656839f, -0.012681897f, -0.012706185f, -0.012729709f, -0.012752469f, + -0.012774469f, -0.012795713f, -0.012816204f, -0.012835944f, -0.012854930f, + -0.012873179f, -0.012890689f, -0.012907463f, -0.012923501f, -0.012938812f, + -0.012953395f, -0.012967254f, -0.012980393f, -0.012992817f, -0.013004529f, + -0.013015532f, -0.013025828f, -0.013035421f, -0.013044316f, -0.013052518f, + -0.013060026f, -0.013066847f, -0.013072984f, -0.013078442f, -0.013083221f, + -0.013087329f, -0.013090767f, -0.013093537f, -0.013095647f, -0.013097100f, + -0.013097897f, -0.013098043f, -0.013097542f, -0.013096399f, -0.013094617f, + -0.013092197f, -0.013089147f, -0.013085471f, -0.013081170f, -0.013076247f, + -0.013070711f, -0.013064560f, -0.013057803f, -0.013050442f, -0.013042479f, + -0.013033919f, -0.013024768f, -0.013015027f, -0.013004702f, -0.012993797f, + -0.012982314f, -0.012970260f, -0.012957636f, -0.012944449f, -0.012930701f, + -0.012916395f, -0.012901539f, -0.012886133f, -0.012870182f, -0.012853689f, + -0.012836664f, -0.012819104f, -0.012801019f, -0.012782406f, -0.012763276f, + -0.012743629f, -0.012723471f, -0.012702805f, -0.012681637f, -0.012659966f, + -0.012637801f, -0.012615148f, -0.012592005f, -0.012568381f, -0.012544277f, + -0.012519698f, -0.012494650f, -0.012469133f, -0.012443157f, -0.012416720f, + -0.012389832f, -0.012362492f, -0.012334707f, -0.012306482f, -0.012277817f, + -0.012248720f, -0.012219194f, -0.012189244f, -0.012158873f, -0.012128084f, + -0.012096884f, -0.012065274f, -0.012033261f, -0.012000849f, -0.011968041f, + -0.011934839f, -0.011901250f, -0.011867279f, -0.011832927f, -0.011798202f, + -0.011763104f, -0.011727640f, -0.011691812f, -0.011655626f, -0.011619086f, + -0.011582195f, -0.011544957f, -0.011507377f, -0.011469459f, -0.011431207f, + -0.011392625f, -0.011353718f, -0.011314487f, -0.011274938f, -0.011235079f, + -0.011194907f, -0.011154431f, -0.011113651f, -0.011072575f, -0.011031206f, + -0.010989547f, -0.010947601f, -0.010905375f, -0.010862871f, -0.010820094f, + -0.010777046f, -0.010733733f, -0.010690158f, -0.010646327f, -0.010602240f, + -0.010557905f, -0.010513324f, -0.010468500f, -0.010423439f, -0.010378144f, + -0.010332618f, -0.010286866f, -0.010240891f, -0.010194698f, -0.010148291f, + -0.010101672f, -0.010054846f, -0.010007816f, -0.009960588f, -0.009913164f, + -0.009865548f, -0.009817744f, -0.009769755f, -0.009721586f, -0.009673241f, + -0.009624721f, -0.009576033f, -0.009527179f, -0.009478163f, -0.009428989f, + -0.009379660f, -0.009330180f, -0.009280552f, -0.009230781f, -0.009180869f, + -0.009130822f, -0.009080641f, -0.009030331f, -0.008979894f, -0.008929336f, + -0.008878659f, -0.008827867f, -0.008776963f, -0.008725950f, -0.008674833f, + -0.008623619f, -0.008572303f, -0.008520893f, -0.008469390f, -0.008417801f, + -0.008366127f, -0.008314372f, -0.008262540f, -0.008210634f, -0.008158657f, + -0.008106613f, -0.008054503f, -0.008002332f, -0.007950104f, -0.007897821f, + -0.007845488f, -0.007793106f, -0.007740679f, -0.007688211f, -0.007635703f, + -0.007583159f, -0.007530585f, -0.007477981f, -0.007425350f, -0.007372697f, + -0.007320023f, -0.007267332f, -0.007214627f, -0.007161912f, -0.007109188f, + -0.007056459f, -0.007003729f, -0.006951000f, -0.006898273f, -0.006845553f, + -0.006792843f, -0.006740147f, -0.006687465f, -0.006634800f, -0.006582157f, + -0.006529537f, -0.006476944f, -0.006424380f, -0.006371849f, -0.006319351f, + -0.006266891f, -0.006214471f, -0.006162094f, -0.006109761f, -0.006057477f, + -0.006005243f, -0.005953063f, -0.005900938f, -0.005848871f, -0.005796865f, + -0.005744927f, -0.005693051f, -0.005641241f, -0.005589503f, -0.005537837f, + -0.005486248f, -0.005434736f, -0.005383304f, -0.005331955f, -0.005280690f, + -0.005229514f, -0.005178426f, -0.005127430f, -0.005076529f, -0.005025723f, + -0.004975016f, -0.004924410f, -0.004873907f, -0.004823509f, -0.004773218f, + -0.004723036f, -0.004672966f, -0.004623009f, -0.004573168f, -0.004523444f, + -0.004473840f, -0.004424357f, -0.004374999f, -0.004325765f, -0.004276660f, + -0.004227683f, -0.004178838f, -0.004130126f, -0.004081549f, -0.004033110f, + -0.003984808f, -0.003936647f, -0.003888629f, -0.003840754f, -0.003793026f, + -0.003745445f, -0.003698014f, -0.003650733f, -0.003603605f, -0.003556631f, + -0.003509813f, -0.003463153f, -0.003416652f, -0.003370312f, -0.003324133f, + -0.003278119f, -0.003232269f, -0.003186587f, -0.003141073f, -0.003095729f, + -0.003050560f, -0.003005560f, -0.002960733f, -0.002916081f, -0.002871606f, + -0.002827310f, -0.002783192f, -0.002739255f, -0.002695500f, -0.002651928f, + -0.002608541f, -0.002565339f, -0.002522324f, -0.002479498f, -0.002436860f, + -0.002394413f, -0.002352157f, -0.002310094f, -0.002268225f, -0.002226550f, + -0.002185071f, -0.002143790f, -0.002102705f, -0.002061821f, -0.002021135f, + -0.001980651f, -0.001940368f, -0.001900289f, -0.001860412f, -0.001820740f, + -0.001781274f, -0.001742014f, -0.001702961f, -0.001664116f, -0.001625479f, + -0.001587052f, -0.001548836f, -0.001510830f, -0.001473036f, -0.001435455f, + -0.001398086f, -0.001360932f, -0.001323992f, -0.001287267f, -0.001250757f, + -0.001214464f, -0.001178389f, -0.001142530f, -0.001106890f, -0.001071468f, + -0.001036266f, -0.001001283f, -0.000966520f, -0.000931978f, -0.000897657f, + -0.000863557f, -0.000829685f, -0.000796029f, -0.000762597f, -0.000729387f, + -0.000696401f, -0.000663639f, -0.000631101f, -0.000598788f, -0.000566699f, + -0.000534836f, -0.000503197f, -0.000471784f, -0.000440597f, -0.000409636f, + -0.000378901f, -0.000348393f, -0.000318111f, -0.000288056f, -0.000258228f, + -0.000228626f, -0.000199252f, -0.000170105f, -0.000141186f, -0.000112493f, + -0.000084028f, -0.000055791f, -0.000027781f, 0.000000002f, 0.000027557f, + 0.000054884f, 0.000081984f, 0.000108857f, 0.000135502f, 0.000161920f, + 0.000188111f, 0.000214075f, 0.000239812f, 0.000265322f, 0.000290606f, + 0.000315663f, 0.000340493f, 0.000365097f, 0.000389476f, 0.000413628f, + 0.000437555f, 0.000461256f, 0.000484733f, 0.000507984f, 0.000531011f, + 0.000553814f, 0.000576393f, 0.000598748f, 0.000620879f, 0.000642788f, + 0.000664473f, 0.000685933f, 0.000707174f, 0.000728194f, 0.000748993f, + 0.000769570f, 0.000789927f, 0.000810064f, 0.000829982f, 0.000849680f, + 0.000869160f, 0.000888421f, 0.000907465f, 0.000926291f, 0.000944901f, + 0.000963294f, 0.000981472f, 0.000999434f, 0.001017181f, 0.001034715f, + 0.001052034f, 0.001069141f, 0.001086035f, 0.001102717f, 0.001119188f, + 0.001135448f, 0.001151499f, 0.001167339f, 0.001182971f, 0.001198395f, + 0.001213611f, 0.001228620f, 0.001243423f, 0.001258021f, 0.001272413f, + 0.001286602f, 0.001300586f, 0.001314368f, 0.001327948f, 0.001341327f, + 0.001354505f, 0.001367483f, 0.001380263f, 0.001392843f, 0.001405226f, + 0.001417413f, 0.001429403f, 0.001441198f, 0.001452798f, 0.001464205f, + 0.001475418f, 0.001486440f, 0.001497271f, 0.001507911f, 0.001518361f, + 0.001528623f, 0.001538696f, 0.001548581f, 0.001558281f, 0.001567796f, + 0.001577127f, 0.001586274f, 0.001595238f, 0.001604020f, 0.001612622f, + 0.001621043f, 0.001629285f, 0.001637349f, 0.001645236f, 0.001652946f, + 0.001660481f, 0.001667841f, 0.001675027f, 0.001682041f, 0.001688883f, + 0.001695554f, 0.001702055f, 0.001708387f, 0.001714552f, 0.001720549f, + 0.001726380f, 0.001732047f, 0.001737549f, 0.001742888f, 0.001748065f, + 0.001753081f, 0.001757936f, 0.001762632f, 0.001767171f, 0.001771552f, + 0.001775777f, 0.001779847f, 0.001783762f, 0.001787525f, 0.001791135f, + 0.001794595f, 0.001797904f, 0.001801064f, 0.001804076f, 0.001806941f, + 0.001809660f, 0.001812234f, 0.001814664f, 0.001816952f, 0.001819097f, + 0.001821102f, 0.001822967f, 0.001824693f, 0.001826282f, 0.001827733f, + 0.001829050f, 0.001830231f, 0.001831278f, 0.001832194f, 0.001832979f, + 0.001833633f, 0.001834158f, 0.001834554f, 0.001834824f, 0.001834967f, + 0.001834986f, 0.001834880f, 0.001834651f, 0.001834301f, 0.001833830f, + 0.001833239f, 0.001832529f, 0.001831702f, 0.001830758f, 0.001829698f, + 0.001828525f, 0.001827237f, 0.001825838f, 0.001824327f, 0.001822706f, + 0.001820976f, 0.001819138f, 0.001817193f, 0.001815141f, 0.001812985f, + 0.001810725f, 0.001808363f, 0.001805898f, 0.001803333f, 0.001800668f, + 0.001797904f, 0.001795043f, 0.001792086f, 0.001789033f, 0.001785886f, + 0.001782645f, 0.001779312f, 0.001775887f, 0.001772373f, 0.001768769f, + 0.001765078f, 0.001761299f, 0.001757434f, 0.001753483f, 0.001749449f, + 0.001745332f, 0.001741133f, 0.001736853f, 0.001732493f, 0.001728054f, + 0.001723537f, 0.001718944f, 0.001714273f, 0.001709529f, 0.001704710f, + 0.001699819f, 0.001694857f, 0.001689823f, 0.001684719f, 0.001679546f, + 0.001674306f, 0.001668998f, 0.001663625f, 0.001658187f, 0.001652685f, + 0.001647120f, 0.001641493f, 0.001635804f, 0.001630056f, 0.001624249f, + 0.001618383f, 0.001612461f, 0.001606481f, 0.001600448f, 0.001594359f, + 0.001588217f, 0.001582022f, 0.001575776f, 0.001569480f, 0.001563134f, + 0.001556739f, 0.001550296f, 0.001543806f, 0.001537270f, 0.001530689f, + 0.001524064f, 0.001517395f, 0.001510684f, 0.001503932f, 0.001497139f, + 0.001490306f, 0.001483435f, 0.001476525f, 0.001469578f, 0.001462596f, + 0.001455577f, 0.001448524f, 0.001441438f, 0.001434318f, 0.001427167f, + 0.001419984f, 0.001412771f, 0.001405529f, 0.001398258f, 0.001390959f, + 0.001383633f, 0.001376281f, 0.001368903f, 0.001361501f, 0.001354076f, + 0.001346627f, 0.001339155f, 0.001331663f, 0.001324150f, 0.001316617f, + 0.001309064f, 0.001301494f, 0.001293906f, 0.001286301f, 0.001278680f, + 0.001271044f, 0.001263393f, 0.001255728f, 0.001248050f, 0.001240360f, + 0.001232658f, 0.001224945f, 0.001217221f, 0.001209488f, 0.001201747f, + 0.001193997f, 0.001186240f, 0.001178476f, 0.001170706f, 0.001162930f, + 0.001155150f, 0.001147365f, 0.001139577f, 0.001131787f, 0.001123994f, + 0.001116200f, 0.001108405f, 0.001100609f, 0.001092814f, 0.001085020f, + 0.001077228f, 0.001069438f, 0.001061651f, 0.001053867f, 0.001046087f, + 0.001038312f, 0.001030542f, 0.001022778f, 0.001015020f, 0.001007270f, + 0.000999526f, 0.000991791f, 0.000984065f, 0.000976347f, 0.000968640f, + 0.000960942f, 0.000953256f, 0.000945580f, 0.000937917f, 0.000930266f, + 0.000922628f, 0.000915002f, 0.000907391f, 0.000899794f, 0.000892212f, + 0.000884646f, 0.000877095f, 0.000869560f, 0.000862042f, 0.000854541f, + 0.000847058f, 0.000839593f, 0.000832147f, 0.000824719f, 0.000817311f, + 0.000809923f, 0.000802555f, 0.000795208f, 0.000787881f, 0.000780577f, + 0.000773294f, 0.000766033f, 0.000758795f, 0.000751581f, 0.000744389f, + 0.000737222f, 0.000730079f, 0.000722960f, 0.000715866f, 0.000708798f, + 0.000701755f, 0.000694738f, 0.000687748f, 0.000680784f, 0.000673847f, + 0.000666937f, 0.000660055f, 0.000653202f, 0.000646376f, 0.000639579f, + 0.000632810f, 0.000626071f, 0.000619362f, 0.000612682f, 0.000606032f, + 0.000599412f, 0.000592823f, 0.000586265f, 0.000579738f, 0.000573242f, + 0.000566777f, 0.000560345f, 0.000553944f, 0.000547577f, 0.000541241f, + 0.000534938f, 0.000528668f, 0.000522432f, 0.000516228f, 0.000510059f, + 0.000503923f, 0.000497821f, 0.000491753f, 0.000485720f, 0.000479721f, + 0.000473757f, 0.000467828f, 0.000461934f, 0.000456075f, 0.000450252f, + 0.000444464f, 0.000438712f, 0.000432996f, 0.000427316f, 0.000421672f, + 0.000416064f, 0.000410493f, 0.000404958f, 0.000399460f, 0.000393998f, + 0.000388574f, 0.000383186f, 0.000377836f, 0.000372523f, 0.000367247f, + 0.000362008f, 0.000356807f, 0.000351643f, 0.000346517f, 0.000341429f, + 0.000336378f, 0.000331366f, 0.000326391f, 0.000321454f, 0.000316555f, + 0.000311695f, 0.000306872f, 0.000302088f, 0.000297341f, 0.000292633f, + 0.000287963f, 0.000283332f, 0.000278739f, 0.000274184f, 0.000269667f, + 0.000265189f, 0.000260749f, 0.000256348f, 0.000251985f, 0.000247661f, + 0.000243374f, 0.000239126f, 0.000234917f, 0.000230745f, 0.000226613f, + 0.000222518f, 0.000218462f, 0.000214443f, 0.000210464f, 0.000206522f, + 0.000202618f, 0.000198753f, 0.000194926f, 0.000191136f, 0.000187385f, + 0.000183671f, 0.000179996f, 0.000176358f, 0.000172758f, 0.000169195f, + 0.000165670f, 0.000162183f, 0.000158733f, 0.000155321f, 0.000151945f, + 0.000148607f, 0.000145307f, 0.000142043f, 0.000138816f, 0.000135626f, + 0.000132473f, 0.000129356f, 0.000126276f, 0.000123233f, 0.000120225f, + 0.000117255f, 0.000114320f, 0.000111421f, 0.000108558f, 0.000105731f, + 0.000102940f, 0.000100184f, 0.000097463f, 0.000094778f, 0.000092128f, + 0.000089513f, 0.000086933f, 0.000084388f, 0.000081878f, 0.000079402f, + 0.000076960f, 0.000074552f, 0.000072179f, 0.000069839f, 0.000067534f, + 0.000065261f, 0.000063023f, 0.000060817f, 0.000058645f, 0.000056506f, + 0.000054399f, 0.000052326f, 0.000050284f, 0.000048275f, 0.000046299f, + 0.000044354f, 0.000042441f, 0.000040560f, 0.000038710f, 0.000036891f, + 0.000035104f, 0.000033348f, 0.000031622f, 0.000029927f, 0.000028263f, + 0.000026628f, 0.000025024f, 0.000023450f, 0.000021905f, 0.000020390f, + 0.000018904f, 0.000017447f, 0.000016019f, 0.000014620f, 0.000013249f, + 0.000011907f, 0.000010593f, 0.000009307f, 0.000008048f, 0.000006818f, + 0.000005614f, 0.000004438f, 0.000003288f, 0.000002166f, 0.000001070f, + -0.000000000f +}; + +static const float ResamplerFilterDifference[RESAMPLER_FILTER_SIZE] = { + -0.000006318f, -0.000019312f, -0.000033081f, -0.000046730f, -0.000060380f, + -0.000074029f, -0.000087738f, -0.000101388f, -0.000115037f, -0.000128686f, + -0.000142336f, -0.000155985f, -0.000169694f, -0.000183165f, -0.000196993f, + -0.000210524f, -0.000224173f, -0.000237763f, -0.000251293f, -0.000265062f, + -0.000278592f, -0.000292122f, -0.000305772f, -0.000319421f, -0.000332832f, + -0.000346422f, -0.000359952f, -0.000373542f, -0.000387073f, -0.000400543f, + -0.000414014f, -0.000427663f, -0.000441074f, -0.000454485f, -0.000468016f, + -0.000481427f, -0.000494778f, -0.000508308f, -0.000521660f, -0.000535011f, + -0.000548482f, -0.000561833f, -0.000575066f, -0.000588536f, -0.000601768f, + -0.000615180f, -0.000628352f, -0.000641525f, -0.000655055f, -0.000668049f, + -0.000681281f, -0.000694513f, -0.000707746f, -0.000720799f, -0.000733972f, + -0.000747204f, -0.000760138f, -0.000773191f, -0.000786424f, -0.000799239f, + -0.000812411f, -0.000825346f, -0.000838339f, -0.000851214f, -0.000864267f, + -0.000877023f, -0.000890017f, -0.000902772f, -0.000915587f, -0.000928521f, + -0.000941217f, -0.000953972f, -0.000966668f, -0.000979364f, -0.000992119f, + -0.001004696f, -0.001017392f, -0.001029909f, -0.001042426f, -0.001055002f, + -0.001067519f, -0.001080096f, -0.001092434f, -0.001104832f, -0.001117289f, + -0.001129627f, -0.001141965f, -0.001154304f, -0.001166403f, -0.001178861f, + -0.001191020f, -0.001203120f, -0.001215160f, -0.001227558f, -0.001239419f, + -0.001251400f, -0.001263618f, -0.001275480f, -0.001287460f, -0.001299262f, + -0.001311302f, -0.001322985f, -0.001334965f, -0.001346648f, -0.001358271f, + -0.001370072f, -0.001381695f, -0.001393259f, -0.001404881f, -0.001416504f, + -0.001427948f, -0.001439393f, -0.001450837f, -0.001462340f, -0.001473546f, + -0.001484871f, -0.001496255f, -0.001507342f, -0.001518726f, -0.001529694f, + -0.001540840f, -0.001552045f, -0.001562893f, -0.001574039f, -0.001584947f, + -0.001595795f, -0.001606703f, -0.001617491f, -0.001628280f, -0.001639009f, + -0.001649678f, -0.001660407f, -0.001670957f, -0.001681507f, -0.001692057f, + -0.001702428f, -0.001713037f, -0.001723289f, -0.001733601f, -0.001743913f, + -0.001754165f, -0.001764417f, -0.001774490f, -0.001784563f, -0.001794696f, + -0.001804650f, -0.001814663f, -0.001824498f, -0.001834452f, -0.001844168f, + -0.001854002f, -0.001863778f, -0.001873314f, -0.001883030f, -0.001892567f, + -0.001902103f, -0.001911521f, -0.001920938f, -0.001930356f, -0.001939654f, + -0.001948893f, -0.001958191f, -0.001967311f, -0.001976430f, -0.001985550f, + -0.001994491f, -0.002003491f, -0.002012312f, -0.002021313f, -0.002030015f, + -0.002038717f, -0.002047479f, -0.002056181f, -0.002064645f, -0.002073288f, + -0.002081692f, -0.002090156f, -0.002098501f, -0.002106905f, -0.002115071f, + -0.002123356f, -0.002131462f, -0.002139568f, -0.002147555f, -0.002155662f, + -0.002163529f, -0.002171457f, -0.002179205f, -0.002187014f, -0.002194703f, + -0.002202272f, -0.002209961f, -0.002217531f, -0.002224922f, -0.002232373f, + -0.002239764f, -0.002247095f, -0.002254248f, -0.002261519f, -0.002268672f, + -0.002275705f, -0.002282679f, -0.002289712f, -0.002296627f, -0.002303362f, + -0.002310216f, -0.002316952f, -0.002323568f, -0.002330244f, -0.002336800f, + -0.002343237f, -0.002349675f, -0.002356052f, -0.002362311f, -0.002368629f, + -0.002374828f, -0.002380908f, -0.002386987f, -0.002392948f, -0.002398968f, + -0.002404809f, -0.002410650f, -0.002416372f, -0.002422094f, -0.002427757f, + -0.002433360f, -0.002438903f, -0.002444327f, -0.002449691f, -0.002455056f, + -0.002460301f, -0.002465487f, -0.002470732f, -0.002475739f, -0.002480865f, + -0.002485693f, -0.002490699f, -0.002495527f, -0.002500176f, -0.002505064f, + -0.002509654f, -0.002514243f, -0.002518773f, -0.002523303f, -0.002527595f, + -0.002531946f, -0.002536356f, -0.002540410f, -0.002544582f, -0.002548754f, + -0.002552748f, -0.002556741f, -0.002560616f, -0.002564371f, -0.002568305f, + -0.002571881f, -0.002575636f, -0.002579153f, -0.002582669f, -0.002586126f, + -0.002589583f, -0.002592862f, -0.002596140f, -0.002599359f, -0.002602518f, + -0.002605557f, -0.002608538f, -0.002611578f, -0.002614439f, -0.002617240f, + -0.002620041f, -0.002622724f, -0.002625346f, -0.002627909f, -0.002630413f, + -0.002632916f, -0.002635241f, -0.002637565f, -0.002639830f, -0.002642035f, + -0.002644122f, -0.002646267f, -0.002648175f, -0.002650142f, -0.002652109f, + -0.002653837f, -0.002655566f, -0.002657294f, -0.002658904f, -0.002660453f, + -0.002662003f, -0.002663374f, -0.002664745f, -0.002666116f, -0.002667189f, + -0.002668560f, -0.002669632f, -0.002670705f, -0.002671599f, -0.002672642f, + -0.002673417f, -0.002674311f, -0.002675056f, -0.002675682f, -0.002676308f, + -0.002676874f, -0.002677381f, -0.002677768f, -0.002678156f, -0.002678514f, + -0.002678722f, -0.002678931f, -0.002679020f, -0.002679110f, -0.002679020f, + -0.002679050f, -0.002678901f, -0.002678722f, -0.002678484f, -0.002678186f, + -0.002677828f, -0.002677292f, -0.002676904f, -0.002676338f, -0.002675682f, + -0.002675027f, -0.002674311f, -0.002673507f, -0.002672672f, -0.002671778f, + -0.002670765f, -0.002669752f, -0.002668649f, -0.002667487f, -0.002666295f, + -0.002665013f, -0.002663702f, -0.002662301f, -0.002660841f, -0.002659231f, + -0.002657771f, -0.002656132f, -0.002654433f, -0.002652735f, -0.002650917f, + -0.002649069f, -0.002647102f, -0.002645165f, -0.002643138f, -0.002641022f, + -0.002638906f, -0.002636671f, -0.002634317f, -0.002632141f, -0.002629727f, + -0.002627254f, -0.002624840f, -0.002622217f, -0.002619684f, -0.002616972f, + -0.002614290f, -0.002611518f, -0.002608687f, -0.002605796f, -0.002602875f, + -0.002599895f, -0.002596736f, -0.002593726f, -0.002590597f, -0.002587378f, + -0.002584100f, -0.002580822f, -0.002577394f, -0.002574027f, -0.002570510f, + -0.002566963f, -0.002563447f, -0.002559751f, -0.002556056f, -0.002552360f, + -0.002548456f, -0.002544701f, -0.002540767f, -0.002536893f, -0.002532810f, + -0.002528816f, -0.002524704f, -0.002520531f, -0.002516329f, -0.002512068f, + -0.002507776f, -0.002503395f, -0.002499044f, -0.002494544f, -0.002489939f, + -0.002485529f, -0.002480894f, -0.002476230f, -0.002471551f, -0.002466798f, + -0.002461985f, -0.002457172f, -0.002452269f, -0.002447322f, -0.002442330f, + -0.002437294f, -0.002432242f, -0.002427101f, -0.002421811f, -0.002416730f, + -0.002411440f, -0.002406135f, -0.002400786f, -0.002395362f, -0.002389938f, + -0.002384409f, -0.002378926f, -0.002373338f, -0.002367705f, -0.002362043f, + -0.002356306f, -0.002350554f, -0.002344713f, -0.002338931f, -0.002333075f, + -0.002327129f, -0.002321184f, -0.002315164f, -0.002309129f, -0.002303004f, + -0.002296925f, -0.002290726f, -0.002284512f, -0.002278253f, -0.002271980f, + -0.002265558f, -0.002259284f, -0.002252862f, -0.002246410f, -0.002239943f, + -0.002233401f, -0.002226844f, -0.002220228f, -0.002213612f, -0.002206936f, + -0.002200201f, -0.002193481f, -0.002186671f, -0.002179854f, -0.002172925f, + -0.002166122f, -0.002159171f, -0.002152205f, -0.002145231f, -0.002138190f, + -0.002131112f, -0.002124026f, -0.002116874f, -0.002109714f, -0.002102517f, + -0.002095275f, -0.002088003f, -0.002080709f, -0.002073303f, -0.002066024f, + -0.002058625f, -0.002051190f, -0.002043739f, -0.002036251f, -0.002028733f, + -0.002021186f, -0.002013609f, -0.002006002f, -0.001998372f, -0.001990698f, + -0.001983009f, -0.001975283f, -0.001967464f, -0.001959760f, -0.001951948f, + -0.001944117f, -0.001936268f, -0.001928370f, -0.001920462f, -0.001912523f, + -0.001904562f, -0.001896568f, -0.001888555f, -0.001880515f, -0.001872454f, + -0.001864363f, -0.001856182f, -0.001848117f, -0.001839954f, -0.001831776f, + -0.001823569f, -0.001815341f, -0.001807092f, -0.001798820f, -0.001790524f, + -0.001782209f, -0.001773877f, -0.001765518f, -0.001757140f, -0.001748742f, + -0.001740261f, -0.001731890f, -0.001723433f, -0.001714959f, -0.001706466f, + -0.001697953f, -0.001689423f, -0.001680876f, -0.001672311f, -0.001663728f, + -0.001655128f, -0.001646512f, -0.001637880f, -0.001629170f, -0.001620566f, + -0.001611889f, -0.001603196f, -0.001594484f, -0.001585761f, -0.001577025f, + -0.001568271f, -0.001559505f, -0.001550728f, -0.001541931f, -0.001533132f, + -0.001524314f, -0.001515483f, -0.001506586f, -0.001497786f, -0.001488928f, + -0.001480050f, -0.001471169f, -0.001462270f, -0.001453366f, -0.001444448f, + -0.001435522f, -0.001426589f, -0.001417641f, -0.001408692f, -0.001399733f, + -0.001390763f, -0.001381733f, -0.001372803f, -0.001363818f, -0.001354810f, + -0.001345813f, -0.001336802f, -0.001327783f, -0.001318768f, -0.001309730f, + -0.001300700f, -0.001291670f, -0.001282625f, -0.001273572f, -0.001264527f, + -0.001255415f, -0.001246415f, -0.001237355f, -0.001228295f, -0.001219213f, + -0.001210161f, -0.001201086f, -0.001192011f, -0.001182951f, -0.001173854f, + -0.001164794f, -0.001155719f, -0.001146644f, -0.001137555f, -0.001128443f, + -0.001119412f, -0.001110330f, -0.001101270f, -0.001092196f, -0.001083128f, + -0.001074038f, -0.001065001f, -0.001055919f, -0.001046866f, -0.001037806f, + -0.001028746f, -0.001019694f, -0.001010656f, -0.001001567f, -0.000992566f, + -0.000983544f, -0.000974506f, -0.000965491f, -0.000956468f, -0.000947453f, + -0.000938453f, -0.000929438f, -0.000920445f, -0.000911482f, -0.000902474f, + -0.000893541f, -0.000884496f, -0.000875585f, -0.000866644f, -0.000857703f, + -0.000848778f, -0.000839837f, -0.000830933f, -0.000822030f, -0.000813127f, + -0.000804260f, -0.000795372f, -0.000786506f, -0.000777654f, -0.000768811f, + -0.000759944f, -0.000751153f, -0.000742361f, -0.000733539f, -0.000724763f, + -0.000716001f, -0.000707224f, -0.000698492f, -0.000689745f, -0.000681043f, + -0.000672325f, -0.000663623f, -0.000654951f, -0.000646278f, -0.000637606f, + -0.000628993f, -0.000620380f, -0.000611767f, -0.000603199f, -0.000594586f, + -0.000586048f, -0.000577524f, -0.000568971f, -0.000560462f, -0.000551969f, + -0.000543505f, -0.000535041f, -0.000526607f, -0.000518143f, -0.000509769f, + -0.000501379f, -0.000493005f, -0.000484675f, -0.000476316f, -0.000468016f, + -0.000459731f, -0.000451431f, -0.000443190f, -0.000434965f, -0.000426725f, + -0.000418544f, -0.000410378f, -0.000402227f, -0.000394091f, -0.000385970f, + -0.000377893f, -0.000369802f, -0.000361770f, -0.000353739f, -0.000345752f, + -0.000337750f, -0.000329792f, -0.000321865f, -0.000313938f, -0.000306055f, + -0.000298187f, -0.000290349f, -0.000282511f, -0.000274733f, -0.000266939f, + -0.000259221f, -0.000251472f, -0.000243768f, -0.000236079f, -0.000228450f, + -0.000220820f, -0.000213221f, -0.000205651f, -0.000198096f, -0.000190571f, + -0.000183061f, -0.000175595f, -0.000168160f, -0.000160739f, -0.000153318f, + -0.000145987f, -0.000138611f, -0.000131324f, -0.000124037f, -0.000116780f, + -0.000109524f, -0.000102326f, -0.000095159f, -0.000088021f, -0.000080869f, + -0.000073805f, -0.000066742f, -0.000059679f, -0.000052691f, -0.000045687f, + -0.000038758f, -0.000031844f, -0.000024930f, -0.000018090f, -0.000011265f, + -0.000004441f, 0.000002325f, 0.000009075f, 0.000015780f, 0.000022471f, + 0.000029117f, 0.000035763f, 0.000042319f, 0.000048906f, 0.000055432f, + 0.000061929f, 0.000068396f, 0.000074849f, 0.000081256f, 0.000087619f, + 0.000093967f, 0.000100300f, 0.000106558f, 0.000112817f, 0.000119045f, + 0.000125214f, 0.000131369f, 0.000137508f, 0.000143588f, 0.000149652f, + 0.000155658f, 0.000161663f, 0.000167638f, 0.000173539f, 0.000179455f, + 0.000185296f, 0.000191167f, 0.000196919f, 0.000202700f, 0.000208423f, + 0.000214115f, 0.000219792f, 0.000225410f, 0.000231013f, 0.000236586f, + 0.000242084f, 0.000247598f, 0.000253052f, 0.000258476f, 0.000263870f, + 0.000269234f, 0.000274554f, 0.000279859f, 0.000285104f, 0.000290334f, + 0.000295490f, 0.000300661f, 0.000305787f, 0.000310853f, 0.000315934f, + 0.000320926f, 0.000325903f, 0.000330850f, 0.000335768f, 0.000340641f, + 0.000345469f, 0.000350282f, 0.000355050f, 0.000359803f, 0.000364468f, + 0.000369161f, 0.000373796f, 0.000378355f, 0.000382945f, 0.000387460f, + 0.000391930f, 0.000396401f, 0.000400826f, 0.000405192f, 0.000409558f, + 0.000413850f, 0.000418127f, 0.000422373f, 0.000426546f, 0.000430748f, + 0.000434861f, 0.000438988f, 0.000443041f, 0.000447050f, 0.000451058f, + 0.000455007f, 0.000458926f, 0.000462815f, 0.000466645f, 0.000470474f, + 0.000474244f, 0.000477999f, 0.000481665f, 0.000485376f, 0.000488982f, + 0.000492588f, 0.000496164f, 0.000499681f, 0.000503168f, 0.000506610f, + 0.000510037f, 0.000513420f, 0.000516787f, 0.000520080f, 0.000523359f, + 0.000526607f, 0.000529751f, 0.000532970f, 0.000536114f, 0.000539184f, + 0.000542283f, 0.000545278f, 0.000548288f, 0.000551224f, 0.000554159f, + 0.000557050f, 0.000559889f, 0.000562698f, 0.000565484f, 0.000568233f, + 0.000570931f, 0.000573598f, 0.000576250f, 0.000578851f, 0.000581399f, + 0.000583932f, 0.000586443f, 0.000588894f, 0.000591323f, 0.000593722f, + 0.000596076f, 0.000598386f, 0.000600673f, 0.000602946f, 0.000605099f, + 0.000607334f, 0.000609480f, 0.000611588f, 0.000613675f, 0.000615716f, + 0.000617720f, 0.000619695f, 0.000621639f, 0.000623547f, 0.000625424f, + 0.000627257f, 0.000629067f, 0.000630826f, 0.000632577f, 0.000634275f, + 0.000635937f, 0.000637576f, 0.000639170f, 0.000640750f, 0.000642270f, + 0.000643790f, 0.000645243f, 0.000646673f, 0.000648089f, 0.000649445f, + 0.000650786f, 0.000652038f, 0.000653364f, 0.000654578f, 0.000655793f, + 0.000656962f, 0.000658102f, 0.000659212f, 0.000660270f, 0.000661321f, + 0.000662334f, 0.000663288f, 0.000664257f, 0.000665158f, 0.000666037f, + 0.000666894f, 0.000667714f, 0.000668481f, 0.000669241f, 0.000669979f, + 0.000670649f, 0.000671312f, 0.000671953f, 0.000672549f, 0.000673100f, + 0.000673652f, 0.000674143f, 0.000674628f, 0.000675075f, 0.000675432f, + 0.000675865f, 0.000676215f, 0.000676543f, 0.000676841f, 0.000677086f, + 0.000677340f, 0.000677533f, 0.000677712f, 0.000677854f, 0.000677958f, + 0.000678062f, 0.000678115f, 0.000678137f, 0.000678144f, 0.000678107f, + 0.000678040f, 0.000677980f, 0.000677846f, 0.000677705f, 0.000677541f, + 0.000677332f, 0.000677109f, 0.000676855f, 0.000676572f, 0.000676263f, + 0.000675920f, 0.000675563f, 0.000675112f, 0.000674754f, 0.000674292f, + 0.000673834f, 0.000673324f, 0.000672799f, 0.000672262f, 0.000671666f, + 0.000671066f, 0.000670440f, 0.000669774f, 0.000669103f, 0.000668388f, + 0.000667654f, 0.000666898f, 0.000666108f, 0.000665307f, 0.000664469f, + 0.000663612f, 0.000662729f, 0.000661820f, 0.000660881f, 0.000659931f, + 0.000658948f, 0.000657942f, 0.000656914f, 0.000655863f, 0.000654746f, + 0.000653688f, 0.000652563f, 0.000651423f, 0.000650249f, 0.000649061f, + 0.000647850f, 0.000646606f, 0.000645354f, 0.000644065f, 0.000642769f, + 0.000641439f, 0.000640094f, 0.000638723f, 0.000637334f, 0.000635926f, + 0.000634488f, 0.000633033f, 0.000631562f, 0.000630064f, 0.000628548f, + 0.000627011f, 0.000625454f, 0.000623874f, 0.000622276f, 0.000620661f, + 0.000619022f, 0.000617364f, 0.000615645f, 0.000613993f, 0.000612279f, + 0.000610547f, 0.000608791f, 0.000607023f, 0.000605229f, 0.000603424f, + 0.000601593f, 0.000599753f, 0.000597889f, 0.000596011f, 0.000594109f, + 0.000592194f, 0.000590262f, 0.000588313f, 0.000586346f, 0.000584361f, + 0.000582362f, 0.000580344f, 0.000578311f, 0.000576260f, 0.000574195f, + 0.000572114f, 0.000570015f, 0.000567904f, 0.000565774f, 0.000563630f, + 0.000561428f, 0.000559297f, 0.000557108f, 0.000554904f, 0.000552687f, + 0.000550454f, 0.000548207f, 0.000545946f, 0.000543671f, 0.000541383f, + 0.000539081f, 0.000536765f, 0.000534437f, 0.000532095f, 0.000529740f, + 0.000527372f, 0.000524992f, 0.000522598f, 0.000520193f, 0.000517776f, + 0.000515345f, 0.000512904f, 0.000510451f, 0.000507986f, 0.000505510f, + 0.000503022f, 0.000500523f, 0.000497975f, 0.000495494f, 0.000492963f, + 0.000490420f, 0.000487870f, 0.000485308f, 0.000482734f, 0.000480153f, + 0.000477560f, 0.000474961f, 0.000472347f, 0.000469729f, 0.000467099f, + 0.000464460f, 0.000461814f, 0.000459160f, 0.000456492f, 0.000453821f, + 0.000451141f, 0.000448450f, 0.000445757f, 0.000443047f, 0.000440339f, + 0.000437619f, 0.000434890f, 0.000432156f, 0.000429420f, 0.000426665f, + 0.000423878f, 0.000421155f, 0.000418384f, 0.000415608f, 0.000412831f, + 0.000410046f, 0.000407251f, 0.000404453f, 0.000401655f, 0.000398841f, + 0.000396032f, 0.000393212f, 0.000390388f, 0.000387559f, 0.000384722f, + 0.000381887f, 0.000379046f, 0.000376200f, 0.000373350f, 0.000370493f, + 0.000367636f, 0.000364775f, 0.000361912f, 0.000359036f, 0.000356171f, + 0.000353293f, 0.000350416f, 0.000347532f, 0.000344623f, 0.000341764f, + 0.000338878f, 0.000335984f, 0.000333097f, 0.000330199f, 0.000327300f, + 0.000324406f, 0.000321500f, 0.000318602f, 0.000315700f, 0.000312794f, + 0.000309892f, 0.000306983f, 0.000304081f, 0.000301171f, 0.000298265f, + 0.000295352f, 0.000292446f, 0.000289541f, 0.000286628f, 0.000283718f, + 0.000280812f, 0.000277914f, 0.000274993f, 0.000272095f, 0.000269186f, + 0.000266258f, 0.000263374f, 0.000260476f, 0.000257570f, 0.000254679f, + 0.000251777f, 0.000248875f, 0.000245985f, 0.000243090f, 0.000240199f, + 0.000237312f, 0.000234425f, 0.000231542f, 0.000228655f, 0.000225779f, + 0.000222903f, 0.000220031f, 0.000217155f, 0.000214294f, 0.000211425f, + 0.000208564f, 0.000205707f, 0.000202853f, 0.000200007f, 0.000197157f, + 0.000194311f, 0.000191480f, 0.000188638f, 0.000185791f, 0.000182983f, + 0.000180162f, 0.000177346f, 0.000174530f, 0.000171725f, 0.000168923f, + 0.000166126f, 0.000163332f, 0.000160541f, 0.000157762f, 0.000154987f, + 0.000152212f, 0.000149447f, 0.000146687f, 0.000143930f, 0.000141181f, + 0.000138439f, 0.000135705f, 0.000132974f, 0.000130247f, 0.000127535f, + 0.000124816f, 0.000122119f, 0.000119418f, 0.000116725f, 0.000114042f, + 0.000111364f, 0.000108674f, 0.000106033f, 0.000103373f, 0.000100728f, + 0.000098083f, 0.000095449f, 0.000092819f, 0.000090208f, 0.000087593f, + 0.000084992f, 0.000082392f, 0.000079807f, 0.000077233f, 0.000074655f, + 0.000072096f, 0.000069536f, 0.000066992f, 0.000064459f, 0.000061929f, + 0.000059403f, 0.000056893f, 0.000054389f, 0.000051897f, 0.000049412f, + 0.000046935f, 0.000044469f, 0.000042010f, 0.000039551f, 0.000037123f, + 0.000034694f, 0.000032268f, 0.000029862f, 0.000027459f, 0.000025064f, + 0.000022691f, 0.000020307f, 0.000017952f, 0.000015602f, 0.000013247f, + 0.000010934f, 0.000008594f, 0.000006288f, 0.000003986f, 0.000001695f, + -0.000000589f, -0.000002854f, -0.000005119f, -0.000007369f, -0.000009615f, + -0.000011832f, -0.000014052f, -0.000016265f, -0.000018459f, -0.000020642f, + -0.000022821f, -0.000024986f, -0.000027131f, -0.000029277f, -0.000031408f, + -0.000033524f, -0.000035629f, -0.000037737f, -0.000039808f, -0.000041891f, + -0.000043951f, -0.000046007f, -0.000048041f, -0.000050064f, -0.000052094f, + -0.000054091f, -0.000056084f, -0.000058070f, -0.000060037f, -0.000061993f, + -0.000063941f, -0.000065874f, -0.000067800f, -0.000069708f, -0.000071604f, + -0.000073489f, -0.000075370f, -0.000077229f, -0.000079080f, -0.000080917f, + -0.000082746f, -0.000084557f, -0.000086352f, -0.000088152f, -0.000089929f, + -0.000091687f, -0.000093438f, -0.000095177f, -0.000096913f, -0.000098623f, + -0.000100322f, -0.000102021f, -0.000103690f, -0.000105359f, -0.000107009f, + -0.000108648f, -0.000110280f, -0.000111893f, -0.000113495f, -0.000115078f, + -0.000116657f, -0.000118230f, -0.000119772f, -0.000121318f, -0.000122838f, + -0.000124350f, -0.000125848f, -0.000127345f, -0.000128813f, -0.000130277f, + -0.000131730f, -0.000133157f, -0.000134595f, -0.000135988f, -0.000137400f, + -0.000138778f, -0.000140157f, -0.000141505f, -0.000142857f, -0.000144191f, + -0.000145517f, -0.000146817f, -0.000148114f, -0.000149388f, -0.000150666f, + -0.000151921f, -0.000153165f, -0.000154395f, -0.000155609f, -0.000156820f, + -0.000158004f, -0.000159189f, -0.000160355f, -0.000161506f, -0.000162646f, + -0.000163775f, -0.000164881f, -0.000165988f, -0.000167083f, -0.000168145f, + -0.000169218f, -0.000170264f, -0.000171307f, -0.000172324f, -0.000173341f, + -0.000174336f, -0.000175327f, -0.000176292f, -0.000177257f, -0.000178207f, + -0.000179138f, -0.000180058f, -0.000180975f, -0.000181865f, -0.000182752f, + -0.000183623f, -0.000184480f, -0.000185326f, -0.000186164f, -0.000186980f, + -0.000187792f, -0.000188582f, -0.000189368f, -0.000190143f, -0.000190891f, + -0.000191648f, -0.000192374f, -0.000193097f, -0.000193801f, -0.000194505f, + -0.000195183f, -0.000195853f, -0.000196513f, -0.000197157f, -0.000197794f, + -0.000198420f, -0.000199001f, -0.000199623f, -0.000200208f, -0.000200782f, + -0.000201344f, -0.000201892f, -0.000202429f, -0.000202954f, -0.000203468f, + -0.000203967f, -0.000204455f, -0.000204936f, -0.000205394f, -0.000205856f, + -0.000206295f, -0.000206724f, -0.000207141f, -0.000207547f, -0.000207946f, + -0.000208326f, -0.000208698f, -0.000209058f, -0.000209408f, -0.000209745f, + -0.000210065f, -0.000210386f, -0.000210684f, -0.000210978f, -0.000211256f, + -0.000211528f, -0.000211783f, -0.000212030f, -0.000212263f, -0.000212491f, + -0.000212703f, -0.000212908f, -0.000213092f, -0.000213277f, -0.000213446f, + -0.000213604f, -0.000213752f, -0.000213886f, -0.000214016f, -0.000214130f, + -0.000214234f, -0.000214327f, -0.000214415f, -0.000214487f, -0.000214545f, + -0.000214605f, -0.000214642f, -0.000214674f, -0.000214696f, -0.000214709f, + -0.000214707f, -0.000214674f, -0.000214679f, -0.000214649f, -0.000214612f, + -0.000214560f, -0.000214502f, -0.000214435f, -0.000214357f, -0.000214268f, + -0.000214169f, -0.000214059f, -0.000213947f, -0.000213819f, -0.000213677f, + -0.000213537f, -0.000213381f, -0.000213215f, -0.000213042f, -0.000212861f, + -0.000212666f, -0.000212466f, -0.000212256f, -0.000212036f, -0.000211809f, + -0.000211569f, -0.000211326f, -0.000211067f, -0.000210807f, -0.000210535f, + -0.000210257f, -0.000209961f, -0.000209667f, -0.000209359f, -0.000209045f, + -0.000208722f, -0.000208389f, -0.000208050f, -0.000207704f, -0.000207344f, + -0.000206983f, -0.000206610f, -0.000206229f, -0.000205842f, -0.000205445f, + -0.000205044f, -0.000204630f, -0.000204211f, -0.000203785f, -0.000203351f, + -0.000202909f, -0.000202459f, -0.000202003f, -0.000201537f, -0.000201069f, + -0.000200586f, -0.000200078f, -0.000199611f, -0.000199108f, -0.000198605f, + -0.000198090f, -0.000197569f, -0.000197043f, -0.000196506f, -0.000195967f, + -0.000195420f, -0.000194865f, -0.000194305f, -0.000193738f, -0.000193163f, + -0.000192585f, -0.000191999f, -0.000191407f, -0.000190807f, -0.000190204f, + -0.000189591f, -0.000188977f, -0.000188354f, -0.000187725f, -0.000187092f, + -0.000186451f, -0.000185805f, -0.000185154f, -0.000184498f, -0.000183835f, + -0.000183167f, -0.000182495f, -0.000181816f, -0.000181132f, -0.000180443f, + -0.000179750f, -0.000179050f, -0.000178346f, -0.000177636f, -0.000176923f, + -0.000176203f, -0.000175480f, -0.000174752f, -0.000174019f, -0.000173280f, + -0.000172539f, -0.000171792f, -0.000171040f, -0.000170285f, -0.000169525f, + -0.000168761f, -0.000167992f, -0.000167220f, -0.000166443f, -0.000165662f, + -0.000164878f, -0.000164090f, -0.000163272f, -0.000162501f, -0.000161701f, + -0.000160898f, -0.000160091f, -0.000159280f, -0.000158466f, -0.000157648f, + -0.000156827f, -0.000156003f, -0.000155175f, -0.000154344f, -0.000153510f, + -0.000152673f, -0.000151833f, -0.000150990f, -0.000150144f, -0.000149295f, + -0.000148444f, -0.000147589f, -0.000146732f, -0.000145872f, -0.000145010f, + -0.000144145f, -0.000143277f, -0.000142408f, -0.000141536f, -0.000140661f, + -0.000139785f, -0.000138906f, -0.000138025f, -0.000137142f, -0.000136257f, + -0.000135370f, -0.000134481f, -0.000133590f, -0.000132697f, -0.000131803f, + -0.000130907f, -0.000130009f, -0.000129110f, -0.000128209f, -0.000127306f, + -0.000126403f, -0.000125497f, -0.000124591f, -0.000123683f, -0.000122774f, + -0.000121864f, -0.000120952f, -0.000120040f, -0.000119127f, -0.000118212f, + -0.000117297f, -0.000116381f, -0.000115445f, -0.000114546f, -0.000113628f, + -0.000112709f, -0.000111789f, -0.000110869f, -0.000109948f, -0.000109027f, + -0.000108106f, -0.000107184f, -0.000106262f, -0.000105340f, -0.000104415f, + -0.000103494f, -0.000102570f, -0.000101647f, -0.000100723f, -0.000099801f, + -0.000098877f, -0.000097955f, -0.000097031f, -0.000096109f, -0.000095187f, + -0.000094265f, -0.000093343f, -0.000092422f, -0.000091502f, -0.000090580f, + -0.000089660f, -0.000088741f, -0.000087823f, -0.000086904f, -0.000085988f, + -0.000085071f, -0.000084155f, -0.000083240f, -0.000082325f, -0.000081412f, + -0.000080500f, -0.000079590f, -0.000078678f, -0.000077770f, -0.000076862f, + -0.000075955f, -0.000075049f, -0.000074145f, -0.000073241f, -0.000072340f, + -0.000071440f, -0.000070541f, -0.000069643f, -0.000068747f, -0.000067852f, + -0.000066960f, -0.000066068f, -0.000065166f, -0.000064289f, -0.000063405f, + -0.000062519f, -0.000061636f, -0.000060757f, -0.000059876f, -0.000058998f, + -0.000058125f, -0.000057249f, -0.000056379f, -0.000055509f, -0.000054643f, + -0.000053776f, -0.000052913f, -0.000052053f, -0.000051194f, -0.000050337f, + -0.000049485f, -0.000048630f, -0.000047781f, -0.000046935f, -0.000046090f, + -0.000045246f, -0.000044407f, -0.000043570f, -0.000042734f, -0.000041903f, + -0.000041073f, -0.000040242f, -0.000039421f, -0.000038599f, -0.000037779f, + -0.000036962f, -0.000036148f, -0.000035339f, -0.000034529f, -0.000033723f, + -0.000032922f, -0.000032122f, -0.000031324f, -0.000030532f, -0.000029741f, + -0.000028951f, -0.000028169f, -0.000027386f, -0.000026607f, -0.000025833f, + -0.000025058f, -0.000024288f, -0.000023524f, -0.000022760f, -0.000022001f, + -0.000021243f, -0.000020491f, -0.000019740f, -0.000018986f, -0.000018249f, + -0.000017510f, -0.000016774f, -0.000016038f, -0.000015311f, -0.000014583f, + -0.000013859f, -0.000013139f, -0.000012424f, -0.000011712f, -0.000011003f, + -0.000010296f, -0.000009594f, -0.000008895f, -0.000008201f, -0.000007508f, + -0.000006821f, -0.000006137f, -0.000005458f, -0.000004780f, -0.000004107f, + -0.000003438f, -0.000002770f, -0.000002110f, -0.000001453f, -0.000000797f, + -0.000000146f, 0.000000501f, 0.000001144f, 0.000001782f, 0.000002420f, + 0.000003050f, 0.000003677f, 0.000004301f, 0.000004923f, 0.000005536f, + 0.000006150f, 0.000006758f, 0.000007361f, 0.000007963f, 0.000008560f, + 0.000009151f, 0.000009741f, 0.000010326f, 0.000010905f, 0.000011482f, + 0.000012054f, 0.000012624f, 0.000013188f, 0.000013747f, 0.000014306f, + 0.000014856f, 0.000015406f, 0.000015951f, 0.000016493f, 0.000017026f, + 0.000017560f, 0.000018085f, 0.000018612f, 0.000019130f, 0.000019647f, + 0.000020158f, 0.000020666f, 0.000021168f, 0.000021671f, 0.000022165f, + 0.000022653f, 0.000023143f, 0.000023624f, 0.000024104f, 0.000024579f, + 0.000025048f, 0.000025516f, 0.000025976f, 0.000026437f, 0.000026888f, + 0.000027340f, 0.000027785f, 0.000028226f, 0.000028664f, 0.000029097f, + 0.000029526f, 0.000029950f, 0.000030371f, 0.000030789f, 0.000031200f, + 0.000031610f, 0.000032012f, 0.000032413f, 0.000032808f, 0.000033202f, + 0.000033589f, 0.000033971f, 0.000034352f, 0.000034725f, 0.000035098f, + 0.000035464f, 0.000035828f, 0.000036187f, 0.000036540f, 0.000036892f, + 0.000037238f, 0.000037580f, 0.000037918f, 0.000038252f, 0.000038582f, + 0.000038907f, 0.000039231f, 0.000039549f, 0.000039860f, 0.000040172f, + 0.000040476f, 0.000040780f, 0.000041076f, 0.000041369f, 0.000041659f, + 0.000041946f, 0.000042226f, 0.000042504f, 0.000042778f, 0.000043048f, + 0.000043313f, 0.000043575f, 0.000043831f, 0.000044088f, 0.000044335f, + 0.000044581f, 0.000044825f, 0.000045061f, 0.000045295f, 0.000045526f, + 0.000045752f, 0.000045975f, 0.000046193f, 0.000046407f, 0.000046619f, + 0.000046826f, 0.000047030f, 0.000047228f, 0.000047424f, 0.000047616f, + 0.000047805f, 0.000047988f, 0.000048169f, 0.000048346f, 0.000048519f, + 0.000048689f, 0.000048853f, 0.000049016f, 0.000049174f, 0.000049329f, + 0.000049480f, 0.000049627f, 0.000049771f, 0.000049912f, 0.000050047f, + 0.000050181f, 0.000050310f, 0.000050437f, 0.000050558f, 0.000050677f, + 0.000050792f, 0.000050904f, 0.000051012f, 0.000051118f, 0.000051214f, + 0.000051316f, 0.000051410f, 0.000051503f, 0.000051589f, 0.000051674f, + 0.000051755f, 0.000051832f, 0.000051906f, 0.000051977f, 0.000052044f, + 0.000052109f, 0.000052171f, 0.000052229f, 0.000052283f, 0.000052333f, + 0.000052382f, 0.000052427f, 0.000052468f, 0.000052508f, 0.000052543f, + 0.000052574f, 0.000052604f, 0.000052631f, 0.000052653f, 0.000052674f, + 0.000052691f, 0.000052704f, 0.000052716f, 0.000052724f, 0.000052729f, + 0.000052730f, 0.000052730f, 0.000052726f, 0.000052720f, 0.000052710f, + 0.000052697f, 0.000052682f, 0.000052664f, 0.000052643f, 0.000052620f, + 0.000052593f, 0.000052564f, 0.000052531f, 0.000052498f, 0.000052460f, + 0.000052420f, 0.000052377f, 0.000052333f, 0.000052284f, 0.000052234f, + 0.000052180f, 0.000052125f, 0.000052067f, 0.000052006f, 0.000051938f, + 0.000051877f, 0.000051809f, 0.000051738f, 0.000051666f, 0.000051590f, + 0.000051512f, 0.000051432f, 0.000051349f, 0.000051265f, 0.000051177f, + 0.000051088f, 0.000050996f, 0.000050901f, 0.000050805f, 0.000050707f, + 0.000050606f, 0.000050503f, 0.000050398f, 0.000050291f, 0.000050182f, + 0.000050070f, 0.000049957f, 0.000049842f, 0.000049724f, 0.000049604f, + 0.000049483f, 0.000049358f, 0.000049234f, 0.000049105f, 0.000048977f, + 0.000048845f, 0.000048712f, 0.000048577f, 0.000048439f, 0.000048302f, + 0.000048161f, 0.000048019f, 0.000047874f, 0.000047728f, 0.000047581f, + 0.000047431f, 0.000047280f, 0.000047128f, 0.000046974f, 0.000046818f, + 0.000046660f, 0.000046501f, 0.000046341f, 0.000046178f, 0.000046015f, + 0.000045849f, 0.000045683f, 0.000045514f, 0.000045344f, 0.000045168f, + 0.000045001f, 0.000044827f, 0.000044652f, 0.000044475f, 0.000044297f, + 0.000044117f, 0.000043937f, 0.000043755f, 0.000043572f, 0.000043387f, + 0.000043201f, 0.000043015f, 0.000042827f, 0.000042638f, 0.000042447f, + 0.000042256f, 0.000042063f, 0.000041869f, 0.000041675f, 0.000041479f, + 0.000041282f, 0.000041084f, 0.000040885f, 0.000040685f, 0.000040484f, + 0.000040283f, 0.000040080f, 0.000039876f, 0.000039672f, 0.000039466f, + 0.000039260f, 0.000039053f, 0.000038845f, 0.000038636f, 0.000038427f, + 0.000038217f, 0.000038006f, 0.000037794f, 0.000037581f, 0.000037368f, + 0.000037155f, 0.000036940f, 0.000036725f, 0.000036509f, 0.000036293f, + 0.000036076f, 0.000035858f, 0.000035640f, 0.000035422f, 0.000035202f, + 0.000034983f, 0.000034763f, 0.000034542f, 0.000034321f, 0.000034100f, + 0.000033873f, 0.000033655f, 0.000033432f, 0.000033209f, 0.000032986f, + 0.000032762f, 0.000032538f, 0.000032313f, 0.000032089f, 0.000031864f, + 0.000031638f, 0.000031413f, 0.000031187f, 0.000030961f, 0.000030735f, + 0.000030508f, 0.000030282f, 0.000030055f, 0.000029828f, 0.000029601f, + 0.000029374f, 0.000029147f, 0.000028920f, 0.000028692f, 0.000028465f, + 0.000028237f, 0.000028010f, 0.000027782f, 0.000027555f, 0.000027328f, + 0.000027100f, 0.000026873f, 0.000026645f, 0.000026418f, 0.000026191f, + 0.000025964f, 0.000025737f, 0.000025510f, 0.000025283f, 0.000025057f, + 0.000024830f, 0.000024604f, 0.000024378f, 0.000024152f, 0.000023927f, + 0.000023702f, 0.000023476f, 0.000023252f, 0.000023027f, 0.000022803f, + 0.000022579f, 0.000022355f, 0.000022132f, 0.000021908f, 0.000021686f, + 0.000021460f, 0.000021241f, 0.000021020f, 0.000020798f, 0.000020578f, + 0.000020357f, 0.000020137f, 0.000019917f, 0.000019698f, 0.000019480f, + 0.000019261f, 0.000019044f, 0.000018826f, 0.000018609f, 0.000018393f, + 0.000018177f, 0.000017962f, 0.000017748f, 0.000017533f, 0.000017320f, + 0.000017107f, 0.000016894f, 0.000016682f, 0.000016471f, 0.000016260f, + 0.000016050f, 0.000015841f, 0.000015632f, 0.000015424f, 0.000015216f, + 0.000015009f, 0.000014803f, 0.000014597f, 0.000014393f, 0.000014188f, + 0.000013985f, 0.000013782f, 0.000013580f, 0.000013379f, 0.000013178f, + 0.000012978f, 0.000012779f, 0.000012581f, 0.000012383f, 0.000012186f, + 0.000011990f, 0.000011795f, 0.000011600f, 0.000011407f, 0.000011214f, + 0.000011022f, 0.000010830f, 0.000010640f, 0.000010450f, 0.000010262f, + 0.000010074f, 0.000009884f, 0.000009700f, 0.000009515f, 0.000009331f, + 0.000009147f, 0.000008964f, 0.000008782f, 0.000008601f, 0.000008421f, + 0.000008242f, 0.000008064f, 0.000007887f, 0.000007710f, 0.000007535f, + 0.000007360f, 0.000007186f, 0.000007014f, 0.000006842f, 0.000006671f, + 0.000006501f, 0.000006332f, 0.000006164f, 0.000005997f, 0.000005831f, + 0.000005667f, 0.000005502f, 0.000005339f, 0.000005177f, 0.000005016f, + 0.000004855f, 0.000004696f, 0.000004538f, 0.000004381f, 0.000004225f, + 0.000004070f, 0.000003916f, 0.000003763f, 0.000003610f, 0.000003459f, + 0.000003309f, 0.000003160f, 0.000003012f, 0.000002865f, 0.000002719f, + 0.000002574f, 0.000002430f, 0.000002287f, 0.000002146f, 0.000002005f, + 0.000001865f, 0.000001726f, 0.000001589f, 0.000001452f, 0.000001316f, + 0.000001182f, 0.000001047f, 0.000000916f, 0.000000785f, 0.000000654f, + 0.000000525f, 0.000000397f, 0.000000270f, 0.000000143f, 0.000000019f, + -0.000000106f, -0.000000228f, -0.000000351f, -0.000000471f, -0.000000591f, + -0.000000710f, -0.000000827f, -0.000000944f, -0.000001059f, -0.000001174f, + -0.000001287f, -0.000001399f, -0.000001511f, -0.000001621f, -0.000001730f, + -0.000001838f, -0.000001945f, -0.000002051f, -0.000002156f, -0.000002260f, + -0.000002363f, -0.000002465f, -0.000002565f, -0.000002665f, -0.000002763f, + -0.000002861f, -0.000002958f, -0.000003053f, -0.000003147f, -0.000003241f, + -0.000003333f, -0.000003424f, -0.000003514f, -0.000003604f, -0.000003692f, + -0.000003779f, -0.000003865f, -0.000003950f, -0.000004034f, -0.000004117f, + -0.000004199f, -0.000004280f, -0.000004360f, -0.000004439f, -0.000004517f, + -0.000004594f, -0.000004670f, -0.000004744f, -0.000004819f, -0.000004891f, + -0.000004963f, -0.000005034f, -0.000005104f, -0.000005173f, -0.000005240f, + -0.000005307f, -0.000005373f, -0.000005438f, -0.000005502f, -0.000005565f, + -0.000005627f, -0.000005688f, -0.000005748f, -0.000005807f, -0.000005866f, + -0.000005922f, -0.000005979f, -0.000006034f, -0.000006089f, -0.000006142f, + -0.000006194f, -0.000006246f, -0.000006297f, -0.000006346f, -0.000006395f, + -0.000006443f, -0.000006490f, -0.000006536f, -0.000006581f, -0.000006625f, + -0.000006668f, -0.000006711f, -0.000006752f, -0.000006793f, -0.000006833f, + -0.000006872f, -0.000006909f, -0.000006947f, -0.000006983f, -0.000007018f, + -0.000007053f, -0.000007086f, -0.000007119f, -0.000007151f, -0.000007183f, + -0.000007213f, -0.000007242f, -0.000007271f, -0.000007299f, -0.000007326f, + -0.000007352f, -0.000007377f, -0.000007402f, -0.000007426f, -0.000007449f, + -0.000007471f, -0.000007493f, -0.000007513f, -0.000007533f, -0.000007552f, + -0.000007570f, -0.000007588f, -0.000007605f, -0.000007621f, -0.000007636f, + -0.000007651f, -0.000007665f, -0.000007678f, -0.000007690f, -0.000007702f, + -0.000007713f, -0.000007723f, -0.000007733f, -0.000007742f, -0.000007750f, + -0.000007757f, -0.000007764f, -0.000007770f, -0.000007775f, -0.000007780f, + -0.000007784f, -0.000007788f, -0.000007791f, -0.000007793f, -0.000007794f, + -0.000007795f, -0.000007795f, -0.000007795f, -0.000007794f, -0.000007792f, + -0.000007790f, -0.000007787f, -0.000007784f, -0.000007780f, -0.000007775f, + -0.000007770f, -0.000007764f, -0.000007758f, -0.000007751f, -0.000007743f, + -0.000007735f, -0.000007726f, -0.000007717f, -0.000007708f, -0.000007698f, + -0.000007687f, -0.000007675f, -0.000007663f, -0.000007651f, -0.000007638f, + -0.000007625f, -0.000007611f, -0.000007597f, -0.000007582f, -0.000007567f, + -0.000007551f, -0.000007535f, -0.000007518f, -0.000007501f, -0.000007483f, + -0.000007465f, -0.000007446f, -0.000007427f, -0.000007408f, -0.000007388f, + -0.000007368f, -0.000007347f, -0.000007326f, -0.000007305f, -0.000007283f, + -0.000007261f, -0.000007238f, -0.000007215f, -0.000007191f, -0.000007168f, + -0.000007143f, -0.000007119f, -0.000007094f, -0.000007068f, -0.000007043f, + -0.000007017f, -0.000006991f, -0.000006964f, -0.000006937f, -0.000006909f, + -0.000006882f, -0.000006854f, -0.000006826f, -0.000006797f, -0.000006768f, + -0.000006739f, -0.000006710f, -0.000006680f, -0.000006650f, -0.000006620f, + -0.000006589f, -0.000006558f, -0.000006527f, -0.000006496f, -0.000006464f, + -0.000006432f, -0.000006400f, -0.000006368f, -0.000006336f, -0.000006303f, + -0.000006270f, -0.000006237f, -0.000006203f, -0.000006170f, -0.000006136f, + -0.000006102f, -0.000006068f, -0.000006033f, -0.000005999f, -0.000005964f, + -0.000005929f, -0.000005894f, -0.000005859f, -0.000005823f, -0.000005788f, + -0.000005752f, -0.000005716f, -0.000005680f, -0.000005644f, -0.000005608f, + -0.000005571f, -0.000005535f, -0.000005498f, -0.000005461f, -0.000005424f, + -0.000005388f, -0.000005350f, -0.000005313f, -0.000005276f, -0.000005239f, + -0.000005201f, -0.000005164f, -0.000005126f, -0.000005088f, -0.000005051f, + -0.000005013f, -0.000004975f, -0.000004937f, -0.000004899f, -0.000004861f, + -0.000004823f, -0.000004784f, -0.000004746f, -0.000004708f, -0.000004670f, + -0.000004632f, -0.000004593f, -0.000004555f, -0.000004517f, -0.000004478f, + -0.000004440f, -0.000004401f, -0.000004363f, -0.000004324f, -0.000004286f, + -0.000004248f, -0.000004210f, -0.000004171f, -0.000004133f, -0.000004095f, + -0.000004056f, -0.000004018f, -0.000003980f, -0.000003942f, -0.000003904f, + -0.000003865f, -0.000003827f, -0.000003789f, -0.000003751f, -0.000003714f, + -0.000003676f, -0.000003638f, -0.000003600f, -0.000003562f, -0.000003525f, + -0.000003487f, -0.000003450f, -0.000003412f, -0.000003375f, -0.000003338f, + -0.000003301f, -0.000003264f, -0.000003227f, -0.000003190f, -0.000003153f, + -0.000003117f, -0.000003080f, -0.000003044f, -0.000003007f, -0.000002971f, + -0.000002935f, -0.000002899f, -0.000002863f, -0.000002827f, -0.000002791f, + -0.000002756f, -0.000002720f, -0.000002685f, -0.000002650f, -0.000002615f, + -0.000002580f, -0.000002545f, -0.000002511f, -0.000002476f, -0.000002442f, + -0.000002408f, -0.000002373f, -0.000002340f, -0.000002306f, -0.000002272f, + -0.000002239f, -0.000002205f, -0.000002172f, -0.000002139f, -0.000002106f, + -0.000002074f, -0.000002041f, -0.000002009f, -0.000001977f, -0.000001945f, + -0.000001913f, -0.000001881f, -0.000001850f, -0.000001818f, -0.000001787f, + -0.000001756f, -0.000001726f, -0.000001695f, -0.000001665f, -0.000001634f, + -0.000001604f, -0.000001574f, -0.000001545f, -0.000001515f, -0.000001486f, + -0.000001457f, -0.000001428f, -0.000001399f, -0.000001371f, -0.000001342f, + -0.000001314f, -0.000001286f, -0.000001258f, -0.000001231f, -0.000001203f, + -0.000001176f, -0.000001149f, -0.000001123f, -0.000001096f, -0.000001070f, + 0.000000000f +}; + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index 539900d84..0b95b417c 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -704,97 +704,7 @@ SDL_Convert51To71(SDL_AudioCVT * cvt, SDL_AudioFormat format) /* SDL's resampler uses a "bandlimited interpolation" algorithm: https://ccrma.stanford.edu/~jos/resample/ */ -#define RESAMPLER_ZERO_CROSSINGS 5 -#define RESAMPLER_BITS_PER_SAMPLE 16 -#define RESAMPLER_SAMPLES_PER_ZERO_CROSSING (1 << ((RESAMPLER_BITS_PER_SAMPLE / 2) + 1)) -#define RESAMPLER_FILTER_SIZE ((RESAMPLER_SAMPLES_PER_ZERO_CROSSING * RESAMPLER_ZERO_CROSSINGS) + 1) - -/* This is a "modified" bessel function, so you can't use POSIX j0() */ -static double -bessel(const double x) -{ - const double xdiv2 = x / 2.0; - double i0 = 1.0f; - double f = 1.0f; - int i = 1; - - while (SDL_TRUE) { - const double diff = SDL_pow(xdiv2, i * 2) / SDL_pow(f, 2); - if (diff < 1.0e-21f) { - break; - } - i0 += diff; - i++; - f *= (double) i; - } - - return i0; -} - -/* build kaiser table with cardinal sine applied to it, and array of differences between elements. */ -static void -kaiser_and_sinc(float *table, float *diffs, const int tablelen, const double beta) -{ - const int lenm1 = tablelen - 1; - const int lenm1div2 = lenm1 / 2; - int i; - - table[0] = 1.0f; - for (i = 1; i < tablelen; i++) { - const double kaiser = bessel(beta * SDL_sqrt(1.0 - SDL_pow(((i - lenm1) / 2.0) / lenm1div2, 2.0))) / bessel(beta); - table[tablelen - i] = (float) kaiser; - } - - for (i = 1; i < tablelen; i++) { - const float x = (((float) i) / ((float) RESAMPLER_SAMPLES_PER_ZERO_CROSSING)) * ((float) M_PI); - table[i] *= SDL_sinf(x) / x; - diffs[i - 1] = table[i] - table[i - 1]; - } - diffs[lenm1] = 0.0f; -} - - -static SDL_SpinLock ResampleFilterSpinlock = 0; -static float *ResamplerFilter = NULL; -static float *ResamplerFilterDifference = NULL; - -int -SDL_PrepareResampleFilter(void) -{ - SDL_AtomicLock(&ResampleFilterSpinlock); - if (!ResamplerFilter) { - /* if dB > 50, beta=(0.1102 * (dB - 8.7)), according to Matlab. */ - const double dB = 80.0; - const double beta = 0.1102 * (dB - 8.7); - const size_t alloclen = RESAMPLER_FILTER_SIZE * sizeof (float); - - ResamplerFilter = (float *) SDL_malloc(alloclen); - if (!ResamplerFilter) { - SDL_AtomicUnlock(&ResampleFilterSpinlock); - return SDL_OutOfMemory(); - } - - ResamplerFilterDifference = (float *) SDL_malloc(alloclen); - if (!ResamplerFilterDifference) { - SDL_free(ResamplerFilter); - ResamplerFilter = NULL; - SDL_AtomicUnlock(&ResampleFilterSpinlock); - return SDL_OutOfMemory(); - } - kaiser_and_sinc(ResamplerFilter, ResamplerFilterDifference, RESAMPLER_FILTER_SIZE, beta); - } - SDL_AtomicUnlock(&ResampleFilterSpinlock); - return 0; -} - -void -SDL_FreeResampleFilter(void) -{ - SDL_free(ResamplerFilter); - SDL_free(ResamplerFilterDifference); - ResamplerFilter = NULL; - ResamplerFilterDifference = NULL; -} +#include "SDL_audio_resampler_filter.h" static int ResamplerPadding(const int inrate, const int outrate) @@ -803,7 +713,7 @@ ResamplerPadding(const int inrate, const int outrate) return 0; } if (inrate > outrate) { - return (int) SDL_ceil(((float) (RESAMPLER_SAMPLES_PER_ZERO_CROSSING * inrate) / ((float) outrate))); + return (int) SDL_ceilf(((float) (RESAMPLER_SAMPLES_PER_ZERO_CROSSING * inrate) / ((float) outrate))); } return RESAMPLER_SAMPLES_PER_ZERO_CROSSING; } @@ -815,33 +725,38 @@ SDL_ResampleAudio(const int chans, const int inrate, const int outrate, const float *inbuf, const int inbuflen, float *outbuf, const int outbuflen) { - const double finrate = (double) inrate; - const double outtimeincr = 1.0 / ((float) outrate); - const double ratio = ((float) outrate) / ((float) inrate); + /* Note that this used to be double, but it looks like we can get by with float in most cases at + almost twice the speed on Intel processors, and orders of magnitude more + on CPUs that need a software fallback for double calculations. */ + typedef float ResampleFloatType; + + const ResampleFloatType finrate = (ResampleFloatType) inrate; + const ResampleFloatType outtimeincr = ((ResampleFloatType) 1.0f) / ((ResampleFloatType) outrate); + const ResampleFloatType ratio = ((float) outrate) / ((float) inrate); const int paddinglen = ResamplerPadding(inrate, outrate); const int framelen = chans * (int)sizeof (float); const int inframes = inbuflen / framelen; const int wantedoutframes = (int) ((inbuflen / framelen) * ratio); /* outbuflen isn't total to write, it's total available. */ const int maxoutframes = outbuflen / framelen; const int outframes = SDL_min(wantedoutframes, maxoutframes); + ResampleFloatType outtime = 0.0f; float *dst = outbuf; - double outtime = 0.0; int i, j, chan; for (i = 0; i < outframes; i++) { const int srcindex = (int) (outtime * inrate); - const double intime = ((double) srcindex) / finrate; - const double innexttime = ((double) (srcindex + 1)) / finrate; - const double interpolation1 = 1.0 - ((innexttime - outtime) / (innexttime - intime)); + const ResampleFloatType intime = ((ResampleFloatType) srcindex) / finrate; + const ResampleFloatType innexttime = ((ResampleFloatType) (srcindex + 1)) / finrate; + const ResampleFloatType indeltatime = innexttime - intime; + const ResampleFloatType interpolation1 = (indeltatime == 0.0f) ? 1.0f : (1.0f - ((innexttime - outtime) / indeltatime)); const int filterindex1 = (int) (interpolation1 * RESAMPLER_SAMPLES_PER_ZERO_CROSSING); - const double interpolation2 = 1.0 - interpolation1; + const ResampleFloatType interpolation2 = 1.0f - interpolation1; const int filterindex2 = (int) (interpolation2 * RESAMPLER_SAMPLES_PER_ZERO_CROSSING); for (chan = 0; chan < chans; chan++) { float outsample = 0.0f; /* do this twice to calculate the sample, once for the "left wing" and then same for the right. */ - /* !!! FIXME: do both wings in one loop */ for (j = 0; (filterindex1 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)) < RESAMPLER_FILTER_SIZE; j++) { const int srcframe = srcindex - j; /* !!! FIXME: we can bubble this conditional out of here by doing a pre loop. */ @@ -849,12 +764,15 @@ SDL_ResampleAudio(const int chans, const int inrate, const int outrate, outsample += (float)(insample * (ResamplerFilter[filterindex1 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)] + (interpolation1 * ResamplerFilterDifference[filterindex1 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)]))); } + /* Do the right wing! */ for (j = 0; (filterindex2 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)) < RESAMPLER_FILTER_SIZE; j++) { + const int jsamples = j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING; const int srcframe = srcindex + 1 + j; /* !!! FIXME: we can bubble this conditional out of here by doing a post loop. */ const float insample = (srcframe >= inframes) ? rpadding[((srcframe - inframes) * chans) + chan] : inbuf[(srcframe * chans) + chan]; - outsample += (float)(insample * (ResamplerFilter[filterindex2 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)] + (interpolation2 * ResamplerFilterDifference[filterindex2 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)]))); + outsample += (float)(insample * (ResamplerFilter[filterindex2 + jsamples] + (interpolation2 * ResamplerFilterDifference[filterindex2 + jsamples]))); } + *(dst++) = outsample; } @@ -1119,10 +1037,6 @@ SDL_BuildAudioResampleCVT(SDL_AudioCVT * cvt, const int dst_channels, return SDL_SetError("No conversion available for these rates"); } - if (SDL_PrepareResampleFilter() < 0) { - return -1; - } - /* Update (cvt) with filter details... */ if (SDL_AddAudioCVTFilter(cvt, filter) < 0) { return -1; @@ -1743,13 +1657,6 @@ SDL_NewAudioStream(const SDL_AudioFormat src_format, return NULL; } - if (SDL_PrepareResampleFilter() < 0) { - SDL_free(retval->resampler_state); - retval->resampler_state = NULL; - SDL_FreeAudioStream(retval); - return NULL; - } - retval->resampler_func = SDL_ResampleAudioStream; retval->reset_resampler_func = SDL_ResetAudioStreamResampler; retval->cleanup_resampler_func = SDL_CleanupAudioStreamResampler; diff --git a/src/audio/netbsd/SDL_netbsdaudio.c b/src/audio/netbsd/SDL_netbsdaudio.c index 6ff81578a..5f021ea37 100644 --- a/src/audio/netbsd/SDL_netbsdaudio.c +++ b/src/audio/netbsd/SDL_netbsdaudio.c @@ -56,7 +56,7 @@ static void NETBSDAUDIO_Status(_THIS) { #ifdef DEBUG_AUDIO - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ audio_info_t info; const struct audio_prinfo *prinfo; @@ -118,7 +118,7 @@ NETBSDAUDIO_Status(_THIS) "", this->spec.format, this->spec.size); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ #endif /* DEBUG_AUDIO */ } diff --git a/src/audio/pulseaudio/SDL_pulseaudio.c b/src/audio/pulseaudio/SDL_pulseaudio.c index a969f2b1f..85e1386c2 100644 --- a/src/audio/pulseaudio/SDL_pulseaudio.c +++ b/src/audio/pulseaudio/SDL_pulseaudio.c @@ -107,8 +107,6 @@ static int (*PULSEAUDIO_pa_stream_connect_record) (pa_stream *, const char *, static pa_stream_state_t (*PULSEAUDIO_pa_stream_get_state) (const pa_stream *); static size_t (*PULSEAUDIO_pa_stream_writable_size) (const pa_stream *); static size_t (*PULSEAUDIO_pa_stream_readable_size) (const pa_stream *); -static int (*PULSEAUDIO_pa_stream_begin_write) (pa_stream *, void **, size_t*); -static int (*PULSEAUDIO_pa_stream_cancel_write) (pa_stream *); static int (*PULSEAUDIO_pa_stream_write) (pa_stream *, const void *, size_t, pa_free_cb_t, int64_t, pa_seek_mode_t); static pa_operation * (*PULSEAUDIO_pa_stream_drain) (pa_stream *, @@ -119,6 +117,7 @@ static pa_operation * (*PULSEAUDIO_pa_stream_flush) (pa_stream *, pa_stream_success_cb_t, void *); static int (*PULSEAUDIO_pa_stream_disconnect) (pa_stream *); static void (*PULSEAUDIO_pa_stream_unref) (pa_stream *); +static void (*PULSEAUDIO_pa_stream_set_write_callback)(pa_stream *, pa_stream_request_cb_t, void *); static int load_pulseaudio_syms(void); @@ -222,8 +221,6 @@ load_pulseaudio_syms(void) SDL_PULSEAUDIO_SYM(pa_stream_writable_size); SDL_PULSEAUDIO_SYM(pa_stream_readable_size); SDL_PULSEAUDIO_SYM(pa_stream_write); - SDL_PULSEAUDIO_SYM(pa_stream_begin_write); - SDL_PULSEAUDIO_SYM(pa_stream_cancel_write); SDL_PULSEAUDIO_SYM(pa_stream_drain); SDL_PULSEAUDIO_SYM(pa_stream_disconnect); SDL_PULSEAUDIO_SYM(pa_stream_peek); @@ -232,6 +229,7 @@ load_pulseaudio_syms(void) SDL_PULSEAUDIO_SYM(pa_stream_unref); SDL_PULSEAUDIO_SYM(pa_channel_map_init_auto); SDL_PULSEAUDIO_SYM(pa_strerror); + SDL_PULSEAUDIO_SYM(pa_stream_set_write_callback); return 0; } @@ -359,51 +357,56 @@ ConnectToPulseServer(pa_mainloop **_mainloop, pa_context **_context) static void PULSEAUDIO_WaitDevice(_THIS) { - struct SDL_PrivateAudioData *h = this->hidden; + /* this is a no-op; we wait in PULSEAUDIO_PlayDevice now. */ +} - while (SDL_AtomicGet(&this->enabled)) { +static void WriteCallback(pa_stream *p, size_t nbytes, void *userdata) +{ + struct SDL_PrivateAudioData *h = (struct SDL_PrivateAudioData *) userdata; + /*printf("PULSEAUDIO WRITE CALLBACK! nbytes=%u\n", (unsigned int) nbytes);*/ + h->bytes_requested += nbytes; +} + +static void +PULSEAUDIO_PlayDevice(_THIS) +{ + struct SDL_PrivateAudioData *h = this->hidden; + int available = h->mixlen; + int written = 0; + int cpy; + + /*printf("PULSEAUDIO PLAYDEVICE START! mixlen=%d\n", available);*/ + + while (SDL_AtomicGet(&this->enabled) && (available > 0)) { + cpy = SDL_min(h->bytes_requested, available); + if (cpy) { + if (PULSEAUDIO_pa_stream_write(h->stream, h->mixbuf + written, cpy, NULL, 0LL, PA_SEEK_RELATIVE) < 0) { + SDL_OpenedAudioDeviceDisconnected(this); + return; + } + /*printf("PULSEAUDIO FEED! nbytes=%u\n", (unsigned int) cpy);*/ + h->bytes_requested -= cpy; + written += cpy; + available -= cpy; + } + + /* let WriteCallback fire if necessary. */ + /*printf("PULSEAUDIO ITERATE!\n");*/ if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY || PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY || PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) { SDL_OpenedAudioDeviceDisconnected(this); return; } - if (PULSEAUDIO_pa_stream_writable_size(h->stream) >= (h->mixlen/8)) { - return; - } } -} -static void -PULSEAUDIO_PlayDevice(_THIS) -{ - /* Write the audio data */ - struct SDL_PrivateAudioData *h = this->hidden; - if (SDL_AtomicGet(&this->enabled)) { - if (PULSEAUDIO_pa_stream_write(h->stream, h->pabuf, h->mixlen, NULL, 0LL, PA_SEEK_RELATIVE) < 0) { - SDL_OpenedAudioDeviceDisconnected(this); - } - } + /*printf("PULSEAUDIO PLAYDEVICE END! written=%d\n", written);*/ } static Uint8 * PULSEAUDIO_GetDeviceBuf(_THIS) { - struct SDL_PrivateAudioData *h = this->hidden; - size_t nbytes = h->mixlen; - int ret; - - ret = PULSEAUDIO_pa_stream_begin_write(h->stream, &h->pabuf, &nbytes); - - if (ret != 0) { - /* fall back it intermediate buffer */ - h->pabuf = h->mixbuf; - } else if (nbytes < h->mixlen) { - PULSEAUDIO_pa_stream_cancel_write(h->stream); - h->pabuf = h->mixbuf; - } - - return (Uint8 *)h->pabuf; + return this->hidden->mixbuf; } @@ -604,9 +607,6 @@ PULSEAUDIO_OpenDevice(_THIS, const char *devname) paspec.format = format; /* Calculate the final parameters for this audio specification */ -#ifdef PA_STREAM_ADJUST_LATENCY - this->spec.samples /= 2; /* Mix in smaller chunck to avoid underruns */ -#endif SDL_CalculateAudioSpec(&this->spec); /* Allocate mixing buffer */ @@ -623,22 +623,12 @@ PULSEAUDIO_OpenDevice(_THIS, const char *devname) paspec.rate = this->spec.freq; /* Reduced prebuffering compared to the defaults. */ -#ifdef PA_STREAM_ADJUST_LATENCY paattr.fragsize = this->spec.size; - /* 2x original requested bufsize */ - paattr.tlength = h->mixlen * 4; + paattr.tlength = h->mixlen; paattr.prebuf = -1; paattr.maxlength = -1; - /* -1 can lead to pa_stream_writable_size() >= mixlen never being true */ - paattr.minreq = h->mixlen; - flags = PA_STREAM_ADJUST_LATENCY; -#else - paattr.fragsize = this->spec.size; - paattr.tlength = h->mixlen*2; - paattr.prebuf = h->mixlen*2; - paattr.maxlength = h->mixlen*2; - paattr.minreq = h->mixlen; -#endif + paattr.minreq = -1; + flags |= PA_STREAM_ADJUST_LATENCY; if (ConnectToPulseServer(&h->mainloop, &h->context) < 0) { return SDL_SetError("Could not connect to PulseAudio server"); @@ -675,6 +665,7 @@ PULSEAUDIO_OpenDevice(_THIS, const char *devname) if (iscapture) { rc = PULSEAUDIO_pa_stream_connect_record(h->stream, h->device_name, &paattr, flags); } else { + PULSEAUDIO_pa_stream_set_write_callback(h->stream, WriteCallback, h); rc = PULSEAUDIO_pa_stream_connect_playback(h->stream, h->device_name, &paattr, flags, NULL, NULL); } diff --git a/src/audio/pulseaudio/SDL_pulseaudio.h b/src/audio/pulseaudio/SDL_pulseaudio.h index a0d0b0c98..7ef45fe25 100644 --- a/src/audio/pulseaudio/SDL_pulseaudio.h +++ b/src/audio/pulseaudio/SDL_pulseaudio.h @@ -43,11 +43,7 @@ struct SDL_PrivateAudioData Uint8 *mixbuf; int mixlen; - /* Pointer to the actual buffer in use in the current - GetDeviceBuf() -> PlayDevice() iteration. - Can be either the pointer returned by pa_stream_begin_write() - or mixbuf */ - void *pabuf; + int bytes_requested; /* bytes of data the hardware wants _now_. */ const Uint8 *capturebuf; int capturelen; diff --git a/src/audio/wasapi/SDL_wasapi_win32.c b/src/audio/wasapi/SDL_wasapi_win32.c index 8e5c7e2a1..137f37013 100644 --- a/src/audio/wasapi/SDL_wasapi_win32.c +++ b/src/audio/wasapi/SDL_wasapi_win32.c @@ -362,7 +362,7 @@ typedef struct WAVEFORMATEXTENSIBLE fmt; } EndpointItem; -static int sort_endpoints(const void *_a, const void *_b) +static int SDLCALL sort_endpoints(const void *_a, const void *_b) { LPWSTR a = ((const EndpointItem *) _a)->devid; LPWSTR b = ((const EndpointItem *) _b)->devid; diff --git a/src/core/linux/SDL_dbus.c b/src/core/linux/SDL_dbus.c index 2fe12163e..ecfbe6f4e 100644 --- a/src/core/linux/SDL_dbus.c +++ b/src/core/linux/SDL_dbus.c @@ -22,6 +22,7 @@ #include "SDL_hints.h" #include "SDL_dbus.h" #include "SDL_atomic.h" +#include "../../stdlib/SDL_vacopy.h" #if SDL_USE_LIBDBUS /* we never link directly to libdbus. */ diff --git a/src/core/windows/SDL_hid.c b/src/core/windows/SDL_hid.c index da9413596..d9dd04fbe 100644 --- a/src/core/windows/SDL_hid.c +++ b/src/core/windows/SDL_hid.c @@ -27,8 +27,6 @@ HidD_GetString_t SDL_HidD_GetManufacturerString; HidD_GetString_t SDL_HidD_GetProductString; -HidD_GetPreparsedData_t SDL_HidD_GetPreparsedData; -HidD_FreePreparsedData_t SDL_HidD_FreePreparsedData; HidP_GetCaps_t SDL_HidP_GetCaps; HidP_GetButtonCaps_t SDL_HidP_GetButtonCaps; HidP_GetValueCaps_t SDL_HidP_GetValueCaps; @@ -58,15 +56,13 @@ WIN_LoadHIDDLL(void) SDL_HidD_GetManufacturerString = (HidD_GetString_t)GetProcAddress(s_pHIDDLL, "HidD_GetManufacturerString"); SDL_HidD_GetProductString = (HidD_GetString_t)GetProcAddress(s_pHIDDLL, "HidD_GetProductString"); - SDL_HidD_GetPreparsedData = (HidD_GetPreparsedData_t)GetProcAddress(s_pHIDDLL, "HidD_GetPreparsedData"); - SDL_HidD_FreePreparsedData = (HidD_FreePreparsedData_t)GetProcAddress(s_pHIDDLL, "HidD_FreePreparsedData"); SDL_HidP_GetCaps = (HidP_GetCaps_t)GetProcAddress(s_pHIDDLL, "HidP_GetCaps"); SDL_HidP_GetButtonCaps = (HidP_GetButtonCaps_t)GetProcAddress(s_pHIDDLL, "HidP_GetButtonCaps"); SDL_HidP_GetValueCaps = (HidP_GetValueCaps_t)GetProcAddress(s_pHIDDLL, "HidP_GetValueCaps"); SDL_HidP_MaxDataListLength = (HidP_MaxDataListLength_t)GetProcAddress(s_pHIDDLL, "HidP_MaxDataListLength"); SDL_HidP_GetData = (HidP_GetData_t)GetProcAddress(s_pHIDDLL, "HidP_GetData"); - if (!SDL_HidD_GetManufacturerString || !SDL_HidD_GetProductString || !SDL_HidD_GetPreparsedData || - !SDL_HidD_FreePreparsedData || !SDL_HidP_GetCaps || !SDL_HidP_GetButtonCaps || + if (!SDL_HidD_GetManufacturerString || !SDL_HidD_GetProductString || + !SDL_HidP_GetCaps || !SDL_HidP_GetButtonCaps || !SDL_HidP_GetValueCaps || !SDL_HidP_MaxDataListLength || !SDL_HidP_GetData) { WIN_UnloadHIDDLL(); return -1; diff --git a/src/core/windows/SDL_hid.h b/src/core/windows/SDL_hid.h index 54b9feb52..82a001a2e 100644 --- a/src/core/windows/SDL_hid.h +++ b/src/core/windows/SDL_hid.h @@ -183,8 +183,6 @@ extern int WIN_LoadHIDDLL(void); extern void WIN_UnloadHIDDLL(void); typedef BOOLEAN (WINAPI *HidD_GetString_t)(HANDLE HidDeviceObject, PVOID Buffer, ULONG BufferLength); -typedef BOOLEAN (WINAPI *HidD_GetPreparsedData_t)(HANDLE HidDeviceObject, PHIDP_PREPARSED_DATA *PreparsedData); -typedef BOOLEAN (WINAPI *HidD_FreePreparsedData_t)(PHIDP_PREPARSED_DATA PreparsedData); typedef NTSTATUS (WINAPI *HidP_GetCaps_t)(PHIDP_PREPARSED_DATA PreparsedData, PHIDP_CAPS Capabilities); typedef NTSTATUS (WINAPI *HidP_GetButtonCaps_t)(HIDP_REPORT_TYPE ReportType, PHIDP_BUTTON_CAPS ButtonCaps, PUSHORT ButtonCapsLength, PHIDP_PREPARSED_DATA PreparsedData); typedef NTSTATUS (WINAPI *HidP_GetValueCaps_t)(HIDP_REPORT_TYPE ReportType, PHIDP_VALUE_CAPS ValueCaps, PUSHORT ValueCapsLength, PHIDP_PREPARSED_DATA PreparsedData); @@ -193,8 +191,6 @@ typedef NTSTATUS (WINAPI *HidP_GetData_t)(HIDP_REPORT_TYPE ReportType, PHIDP_DAT extern HidD_GetString_t SDL_HidD_GetManufacturerString; extern HidD_GetString_t SDL_HidD_GetProductString; -extern HidD_GetPreparsedData_t SDL_HidD_GetPreparsedData; -extern HidD_FreePreparsedData_t SDL_HidD_FreePreparsedData; extern HidP_GetCaps_t SDL_HidP_GetCaps; extern HidP_GetButtonCaps_t SDL_HidP_GetButtonCaps; extern HidP_GetValueCaps_t SDL_HidP_GetValueCaps; diff --git a/src/core/windows/SDL_windows.h b/src/core/windows/SDL_windows.h index 917a8256f..681f01b87 100644 --- a/src/core/windows/SDL_windows.h +++ b/src/core/windows/SDL_windows.h @@ -30,6 +30,8 @@ #ifndef UNICODE #define UNICODE 1 #endif +#undef WINVER +#define WINVER 0x0501 #undef _WIN32_WINNT #define _WIN32_WINNT 0x501 /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices(), 0x501 for raw input */ #endif diff --git a/src/core/windows/SDL_xinput.c b/src/core/windows/SDL_xinput.c index 1893907e4..fa67efcbb 100644 --- a/src/core/windows/SDL_xinput.c +++ b/src/core/windows/SDL_xinput.c @@ -23,8 +23,6 @@ #include "SDL_xinput.h" -#ifdef HAVE_XINPUT_H - XInputGetState_t SDL_XInputGetState = NULL; XInputSetState_t SDL_XInputSetState = NULL; XInputGetCapabilities_t SDL_XInputGetCapabilities = NULL; @@ -137,6 +135,5 @@ WIN_UnloadXInputDLL(void) } #endif /* __WINRT__ */ -#endif /* HAVE_XINPUT_H */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/core/windows/SDL_xinput.h b/src/core/windows/SDL_xinput.h index 6e72327d8..1879e09ad 100644 --- a/src/core/windows/SDL_xinput.h +++ b/src/core/windows/SDL_xinput.h @@ -23,10 +23,11 @@ #ifndef SDL_xinput_h_ #define SDL_xinput_h_ -#ifdef HAVE_XINPUT_H - #include "SDL_windows.h" + +#ifdef HAVE_XINPUT_H #include +#endif /* HAVE_XINPUT_H */ #ifndef XUSER_MAX_COUNT #define XUSER_MAX_COUNT 4 @@ -72,6 +73,53 @@ #define XINPUT_DEVSUBTYPE_ARCADE_PAD 0x13 #endif +#ifndef XINPUT_FLAG_GAMEPAD +#define XINPUT_FLAG_GAMEPAD 0x01 +#endif + +#ifndef XINPUT_GAMEPAD_DPAD_UP +#define XINPUT_GAMEPAD_DPAD_UP 0x0001 +#endif +#ifndef XINPUT_GAMEPAD_DPAD_DOWN +#define XINPUT_GAMEPAD_DPAD_DOWN 0x0002 +#endif +#ifndef XINPUT_GAMEPAD_DPAD_LEFT +#define XINPUT_GAMEPAD_DPAD_LEFT 0x0004 +#endif +#ifndef XINPUT_GAMEPAD_DPAD_RIGHT +#define XINPUT_GAMEPAD_DPAD_RIGHT 0x0008 +#endif +#ifndef XINPUT_GAMEPAD_START +#define XINPUT_GAMEPAD_START 0x0010 +#endif +#ifndef XINPUT_GAMEPAD_BACK +#define XINPUT_GAMEPAD_BACK 0x0020 +#endif +#ifndef XINPUT_GAMEPAD_LEFT_THUMB +#define XINPUT_GAMEPAD_LEFT_THUMB 0x0040 +#endif +#ifndef XINPUT_GAMEPAD_RIGHT_THUMB +#define XINPUT_GAMEPAD_RIGHT_THUMB 0x0080 +#endif +#ifndef XINPUT_GAMEPAD_LEFT_SHOULDER +#define XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100 +#endif +#ifndef XINPUT_GAMEPAD_RIGHT_SHOULDER +#define XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200 +#endif +#ifndef XINPUT_GAMEPAD_A +#define XINPUT_GAMEPAD_A 0x1000 +#endif +#ifndef XINPUT_GAMEPAD_B +#define XINPUT_GAMEPAD_B 0x2000 +#endif +#ifndef XINPUT_GAMEPAD_X +#define XINPUT_GAMEPAD_X 0x4000 +#endif +#ifndef XINPUT_GAMEPAD_Y +#define XINPUT_GAMEPAD_Y 0x8000 +#endif + #ifndef XINPUT_GAMEPAD_GUIDE #define XINPUT_GAMEPAD_GUIDE 0x0400 #endif @@ -129,6 +177,36 @@ typedef struct BYTE BatteryLevel; } XINPUT_BATTERY_INFORMATION_EX; +#ifndef HAVE_XINPUT_H + +typedef struct +{ + WORD wButtons; + BYTE bLeftTrigger; + BYTE bRightTrigger; + SHORT sThumbLX; + SHORT sThumbLY; + SHORT sThumbRX; + SHORT sThumbRY; +} XINPUT_GAMEPAD; + +typedef struct +{ + WORD wLeftMotorSpeed; + WORD wRightMotorSpeed; +} XINPUT_VIBRATION; + +typedef struct +{ + BYTE Type; + BYTE SubType; + WORD Flags; + XINPUT_GAMEPAD Gamepad; + XINPUT_VIBRATION Vibration; +} XINPUT_CAPABILITIES; + +#endif /* HAVE_XINPUT_H */ + /* Forward decl's for XInput API's we load dynamically and use if available */ typedef DWORD (WINAPI *XInputGetState_t) ( @@ -170,8 +248,6 @@ extern DWORD SDL_XInputVersion; /* ((major << 16) & 0xFF00) | (minor & 0xFF) */ #define XINPUTGETCAPABILITIES SDL_XInputGetCapabilities #define XINPUTGETBATTERYINFORMATION SDL_XInputGetBatteryInformation -#endif /* HAVE_XINPUT_H */ - #endif /* SDL_xinput_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/cpuinfo/SDL_cpuinfo.c b/src/cpuinfo/SDL_cpuinfo.c index c82e76b7f..fd42c1872 100644 --- a/src/cpuinfo/SDL_cpuinfo.c +++ b/src/cpuinfo/SDL_cpuinfo.c @@ -130,7 +130,7 @@ CPU_haveCPUID(void) { int has_CPUID = 0; -/* *INDENT-OFF* */ +/* *INDENT-OFF* */ /* clang-format off */ #ifndef SDL_CPUINFO_DISABLED #if (defined(__GNUC__) || defined(__llvm__)) && defined(__i386__) __asm__ ( @@ -219,7 +219,7 @@ done: ); #endif #endif -/* *INDENT-ON* */ +/* *INDENT-ON* */ /* clang-format on */ return has_CPUID; } @@ -1058,10 +1058,18 @@ void * SDL_SIMDAlloc(const size_t len) { const size_t alignment = SDL_SIMDGetAlignment(); - const size_t padding = alignment - (len % alignment); - const size_t padded = (padding != alignment) ? (len + padding) : len; + const size_t padding = (alignment - (len % alignment)) % alignment; Uint8 *retval = NULL; - Uint8 *ptr = (Uint8 *) SDL_malloc(padded + alignment + sizeof (void *)); + Uint8 *ptr; + size_t to_allocate; + + /* alignment + padding + sizeof (void *) is bounded (a few hundred + * bytes max), so no need to check for overflow within that argument */ + if (SDL_size_add_overflow(len, alignment + padding + sizeof (void *), &to_allocate)) { + return NULL; + } + + ptr = (Uint8 *) SDL_malloc(to_allocate); if (ptr) { /* store the actual allocated pointer right before our aligned pointer. */ retval = ptr + sizeof (void *); @@ -1075,12 +1083,18 @@ void * SDL_SIMDRealloc(void *mem, const size_t len) { const size_t alignment = SDL_SIMDGetAlignment(); - const size_t padding = alignment - (len % alignment); - const size_t padded = (padding != alignment) ? (len + padding) : len; + const size_t padding = (alignment - (len % alignment)) % alignment; Uint8 *retval = (Uint8*) mem; void *oldmem = mem; size_t memdiff = 0, ptrdiff; Uint8 *ptr; + size_t to_allocate; + + /* alignment + padding + sizeof (void *) is bounded (a few hundred + * bytes max), so no need to check for overflow within that argument */ + if (SDL_size_add_overflow(len, alignment + padding + sizeof (void *), &to_allocate)) { + return NULL; + } if (mem) { void **realptr = (void **) mem; @@ -1091,7 +1105,7 @@ SDL_SIMDRealloc(void *mem, const size_t len) memdiff = ((size_t) oldmem) - ((size_t) mem); } - ptr = (Uint8 *) SDL_realloc(mem, padded + alignment + sizeof (void *)); + ptr = (Uint8 *) SDL_realloc(mem, to_allocate); if (ptr == NULL) { return NULL; /* Out of memory, bail! */ diff --git a/src/dynapi/SDL2.exports b/src/dynapi/SDL2.exports new file mode 100644 index 000000000..3d09d1108 --- /dev/null +++ b/src/dynapi/SDL2.exports @@ -0,0 +1,843 @@ +# Windows exports file for Watcom +# DO NOT EDIT THIS FILE BY HAND. It is autogenerated by gendynapi.pl. +++'_SDL_DYNAPI_entry'.'SDL2.dll'.'SDL_DYNAPI_entry' +++'_SDL_SetError'.'SDL2.dll'.'SDL_SetError' +++'_SDL_Log'.'SDL2.dll'.'SDL_Log' +++'_SDL_LogVerbose'.'SDL2.dll'.'SDL_LogVerbose' +++'_SDL_LogDebug'.'SDL2.dll'.'SDL_LogDebug' +++'_SDL_LogInfo'.'SDL2.dll'.'SDL_LogInfo' +++'_SDL_LogWarn'.'SDL2.dll'.'SDL_LogWarn' +++'_SDL_LogError'.'SDL2.dll'.'SDL_LogError' +++'_SDL_LogCritical'.'SDL2.dll'.'SDL_LogCritical' +++'_SDL_LogMessage'.'SDL2.dll'.'SDL_LogMessage' +++'_SDL_sscanf'.'SDL2.dll'.'SDL_sscanf' +++'_SDL_snprintf'.'SDL2.dll'.'SDL_snprintf' +++'_SDL_CreateThread'.'SDL2.dll'.'SDL_CreateThread' +++'_SDL_RWFromFP'.'SDL2.dll'.'SDL_RWFromFP' +++'_SDL_RegisterApp'.'SDL2.dll'.'SDL_RegisterApp' +++'_SDL_UnregisterApp'.'SDL2.dll'.'SDL_UnregisterApp' +++'_SDL_Direct3D9GetAdapterIndex'.'SDL2.dll'.'SDL_Direct3D9GetAdapterIndex' +++'_SDL_RenderGetD3D9Device'.'SDL2.dll'.'SDL_RenderGetD3D9Device' +# ++'_SDL_iPhoneSetAnimationCallback'.'SDL2.dll'.'SDL_iPhoneSetAnimationCallback' +# ++'_SDL_iPhoneSetEventPump'.'SDL2.dll'.'SDL_iPhoneSetEventPump' +# ++'_SDL_AndroidGetJNIEnv'.'SDL2.dll'.'SDL_AndroidGetJNIEnv' +# ++'_SDL_AndroidGetActivity'.'SDL2.dll'.'SDL_AndroidGetActivity' +# ++'_SDL_AndroidGetInternalStoragePath'.'SDL2.dll'.'SDL_AndroidGetInternalStoragePath' +# ++'_SDL_AndroidGetExternalStorageState'.'SDL2.dll'.'SDL_AndroidGetExternalStorageState' +# ++'_SDL_AndroidGetExternalStoragePath'.'SDL2.dll'.'SDL_AndroidGetExternalStoragePath' +++'_SDL_Init'.'SDL2.dll'.'SDL_Init' +++'_SDL_InitSubSystem'.'SDL2.dll'.'SDL_InitSubSystem' +++'_SDL_QuitSubSystem'.'SDL2.dll'.'SDL_QuitSubSystem' +++'_SDL_WasInit'.'SDL2.dll'.'SDL_WasInit' +++'_SDL_Quit'.'SDL2.dll'.'SDL_Quit' +++'_SDL_ReportAssertion'.'SDL2.dll'.'SDL_ReportAssertion' +++'_SDL_SetAssertionHandler'.'SDL2.dll'.'SDL_SetAssertionHandler' +++'_SDL_GetAssertionReport'.'SDL2.dll'.'SDL_GetAssertionReport' +++'_SDL_ResetAssertionReport'.'SDL2.dll'.'SDL_ResetAssertionReport' +++'_SDL_AtomicTryLock'.'SDL2.dll'.'SDL_AtomicTryLock' +++'_SDL_AtomicLock'.'SDL2.dll'.'SDL_AtomicLock' +++'_SDL_AtomicUnlock'.'SDL2.dll'.'SDL_AtomicUnlock' +++'_SDL_AtomicCAS'.'SDL2.dll'.'SDL_AtomicCAS' +++'_SDL_AtomicSet'.'SDL2.dll'.'SDL_AtomicSet' +++'_SDL_AtomicGet'.'SDL2.dll'.'SDL_AtomicGet' +++'_SDL_AtomicAdd'.'SDL2.dll'.'SDL_AtomicAdd' +++'_SDL_AtomicCASPtr'.'SDL2.dll'.'SDL_AtomicCASPtr' +++'_SDL_AtomicSetPtr'.'SDL2.dll'.'SDL_AtomicSetPtr' +++'_SDL_AtomicGetPtr'.'SDL2.dll'.'SDL_AtomicGetPtr' +++'_SDL_GetNumAudioDrivers'.'SDL2.dll'.'SDL_GetNumAudioDrivers' +++'_SDL_GetAudioDriver'.'SDL2.dll'.'SDL_GetAudioDriver' +++'_SDL_AudioInit'.'SDL2.dll'.'SDL_AudioInit' +++'_SDL_AudioQuit'.'SDL2.dll'.'SDL_AudioQuit' +++'_SDL_GetCurrentAudioDriver'.'SDL2.dll'.'SDL_GetCurrentAudioDriver' +++'_SDL_OpenAudio'.'SDL2.dll'.'SDL_OpenAudio' +++'_SDL_GetNumAudioDevices'.'SDL2.dll'.'SDL_GetNumAudioDevices' +++'_SDL_GetAudioDeviceName'.'SDL2.dll'.'SDL_GetAudioDeviceName' +++'_SDL_OpenAudioDevice'.'SDL2.dll'.'SDL_OpenAudioDevice' +++'_SDL_GetAudioStatus'.'SDL2.dll'.'SDL_GetAudioStatus' +++'_SDL_GetAudioDeviceStatus'.'SDL2.dll'.'SDL_GetAudioDeviceStatus' +++'_SDL_PauseAudio'.'SDL2.dll'.'SDL_PauseAudio' +++'_SDL_PauseAudioDevice'.'SDL2.dll'.'SDL_PauseAudioDevice' +++'_SDL_LoadWAV_RW'.'SDL2.dll'.'SDL_LoadWAV_RW' +++'_SDL_FreeWAV'.'SDL2.dll'.'SDL_FreeWAV' +++'_SDL_BuildAudioCVT'.'SDL2.dll'.'SDL_BuildAudioCVT' +++'_SDL_ConvertAudio'.'SDL2.dll'.'SDL_ConvertAudio' +++'_SDL_MixAudio'.'SDL2.dll'.'SDL_MixAudio' +++'_SDL_MixAudioFormat'.'SDL2.dll'.'SDL_MixAudioFormat' +++'_SDL_LockAudio'.'SDL2.dll'.'SDL_LockAudio' +++'_SDL_LockAudioDevice'.'SDL2.dll'.'SDL_LockAudioDevice' +++'_SDL_UnlockAudio'.'SDL2.dll'.'SDL_UnlockAudio' +++'_SDL_UnlockAudioDevice'.'SDL2.dll'.'SDL_UnlockAudioDevice' +++'_SDL_CloseAudio'.'SDL2.dll'.'SDL_CloseAudio' +++'_SDL_CloseAudioDevice'.'SDL2.dll'.'SDL_CloseAudioDevice' +++'_SDL_SetClipboardText'.'SDL2.dll'.'SDL_SetClipboardText' +++'_SDL_GetClipboardText'.'SDL2.dll'.'SDL_GetClipboardText' +++'_SDL_HasClipboardText'.'SDL2.dll'.'SDL_HasClipboardText' +++'_SDL_GetCPUCount'.'SDL2.dll'.'SDL_GetCPUCount' +++'_SDL_GetCPUCacheLineSize'.'SDL2.dll'.'SDL_GetCPUCacheLineSize' +++'_SDL_HasRDTSC'.'SDL2.dll'.'SDL_HasRDTSC' +++'_SDL_HasAltiVec'.'SDL2.dll'.'SDL_HasAltiVec' +++'_SDL_HasMMX'.'SDL2.dll'.'SDL_HasMMX' +++'_SDL_Has3DNow'.'SDL2.dll'.'SDL_Has3DNow' +++'_SDL_HasSSE'.'SDL2.dll'.'SDL_HasSSE' +++'_SDL_HasSSE2'.'SDL2.dll'.'SDL_HasSSE2' +++'_SDL_HasSSE3'.'SDL2.dll'.'SDL_HasSSE3' +++'_SDL_HasSSE41'.'SDL2.dll'.'SDL_HasSSE41' +++'_SDL_HasSSE42'.'SDL2.dll'.'SDL_HasSSE42' +++'_SDL_GetSystemRAM'.'SDL2.dll'.'SDL_GetSystemRAM' +++'_SDL_GetError'.'SDL2.dll'.'SDL_GetError' +++'_SDL_ClearError'.'SDL2.dll'.'SDL_ClearError' +++'_SDL_Error'.'SDL2.dll'.'SDL_Error' +++'_SDL_PumpEvents'.'SDL2.dll'.'SDL_PumpEvents' +++'_SDL_PeepEvents'.'SDL2.dll'.'SDL_PeepEvents' +++'_SDL_HasEvent'.'SDL2.dll'.'SDL_HasEvent' +++'_SDL_HasEvents'.'SDL2.dll'.'SDL_HasEvents' +++'_SDL_FlushEvent'.'SDL2.dll'.'SDL_FlushEvent' +++'_SDL_FlushEvents'.'SDL2.dll'.'SDL_FlushEvents' +++'_SDL_PollEvent'.'SDL2.dll'.'SDL_PollEvent' +++'_SDL_WaitEvent'.'SDL2.dll'.'SDL_WaitEvent' +++'_SDL_WaitEventTimeout'.'SDL2.dll'.'SDL_WaitEventTimeout' +++'_SDL_PushEvent'.'SDL2.dll'.'SDL_PushEvent' +++'_SDL_SetEventFilter'.'SDL2.dll'.'SDL_SetEventFilter' +++'_SDL_GetEventFilter'.'SDL2.dll'.'SDL_GetEventFilter' +++'_SDL_AddEventWatch'.'SDL2.dll'.'SDL_AddEventWatch' +++'_SDL_DelEventWatch'.'SDL2.dll'.'SDL_DelEventWatch' +++'_SDL_FilterEvents'.'SDL2.dll'.'SDL_FilterEvents' +++'_SDL_EventState'.'SDL2.dll'.'SDL_EventState' +++'_SDL_RegisterEvents'.'SDL2.dll'.'SDL_RegisterEvents' +++'_SDL_GetBasePath'.'SDL2.dll'.'SDL_GetBasePath' +++'_SDL_GetPrefPath'.'SDL2.dll'.'SDL_GetPrefPath' +++'_SDL_GameControllerAddMapping'.'SDL2.dll'.'SDL_GameControllerAddMapping' +++'_SDL_GameControllerMappingForGUID'.'SDL2.dll'.'SDL_GameControllerMappingForGUID' +++'_SDL_GameControllerMapping'.'SDL2.dll'.'SDL_GameControllerMapping' +++'_SDL_IsGameController'.'SDL2.dll'.'SDL_IsGameController' +++'_SDL_GameControllerNameForIndex'.'SDL2.dll'.'SDL_GameControllerNameForIndex' +++'_SDL_GameControllerOpen'.'SDL2.dll'.'SDL_GameControllerOpen' +++'_SDL_GameControllerName'.'SDL2.dll'.'SDL_GameControllerName' +++'_SDL_GameControllerGetAttached'.'SDL2.dll'.'SDL_GameControllerGetAttached' +++'_SDL_GameControllerGetJoystick'.'SDL2.dll'.'SDL_GameControllerGetJoystick' +++'_SDL_GameControllerEventState'.'SDL2.dll'.'SDL_GameControllerEventState' +++'_SDL_GameControllerUpdate'.'SDL2.dll'.'SDL_GameControllerUpdate' +++'_SDL_GameControllerGetAxisFromString'.'SDL2.dll'.'SDL_GameControllerGetAxisFromString' +++'_SDL_GameControllerGetStringForAxis'.'SDL2.dll'.'SDL_GameControllerGetStringForAxis' +++'_SDL_GameControllerGetBindForAxis'.'SDL2.dll'.'SDL_GameControllerGetBindForAxis' +++'_SDL_GameControllerGetAxis'.'SDL2.dll'.'SDL_GameControllerGetAxis' +++'_SDL_GameControllerGetButtonFromString'.'SDL2.dll'.'SDL_GameControllerGetButtonFromString' +++'_SDL_GameControllerGetStringForButton'.'SDL2.dll'.'SDL_GameControllerGetStringForButton' +++'_SDL_GameControllerGetBindForButton'.'SDL2.dll'.'SDL_GameControllerGetBindForButton' +++'_SDL_GameControllerGetButton'.'SDL2.dll'.'SDL_GameControllerGetButton' +++'_SDL_GameControllerClose'.'SDL2.dll'.'SDL_GameControllerClose' +++'_SDL_RecordGesture'.'SDL2.dll'.'SDL_RecordGesture' +++'_SDL_SaveAllDollarTemplates'.'SDL2.dll'.'SDL_SaveAllDollarTemplates' +++'_SDL_SaveDollarTemplate'.'SDL2.dll'.'SDL_SaveDollarTemplate' +++'_SDL_LoadDollarTemplates'.'SDL2.dll'.'SDL_LoadDollarTemplates' +++'_SDL_NumHaptics'.'SDL2.dll'.'SDL_NumHaptics' +++'_SDL_HapticName'.'SDL2.dll'.'SDL_HapticName' +++'_SDL_HapticOpen'.'SDL2.dll'.'SDL_HapticOpen' +++'_SDL_HapticOpened'.'SDL2.dll'.'SDL_HapticOpened' +++'_SDL_HapticIndex'.'SDL2.dll'.'SDL_HapticIndex' +++'_SDL_MouseIsHaptic'.'SDL2.dll'.'SDL_MouseIsHaptic' +++'_SDL_HapticOpenFromMouse'.'SDL2.dll'.'SDL_HapticOpenFromMouse' +++'_SDL_JoystickIsHaptic'.'SDL2.dll'.'SDL_JoystickIsHaptic' +++'_SDL_HapticOpenFromJoystick'.'SDL2.dll'.'SDL_HapticOpenFromJoystick' +++'_SDL_HapticClose'.'SDL2.dll'.'SDL_HapticClose' +++'_SDL_HapticNumEffects'.'SDL2.dll'.'SDL_HapticNumEffects' +++'_SDL_HapticNumEffectsPlaying'.'SDL2.dll'.'SDL_HapticNumEffectsPlaying' +++'_SDL_HapticQuery'.'SDL2.dll'.'SDL_HapticQuery' +++'_SDL_HapticNumAxes'.'SDL2.dll'.'SDL_HapticNumAxes' +++'_SDL_HapticEffectSupported'.'SDL2.dll'.'SDL_HapticEffectSupported' +++'_SDL_HapticNewEffect'.'SDL2.dll'.'SDL_HapticNewEffect' +++'_SDL_HapticUpdateEffect'.'SDL2.dll'.'SDL_HapticUpdateEffect' +++'_SDL_HapticRunEffect'.'SDL2.dll'.'SDL_HapticRunEffect' +++'_SDL_HapticStopEffect'.'SDL2.dll'.'SDL_HapticStopEffect' +++'_SDL_HapticDestroyEffect'.'SDL2.dll'.'SDL_HapticDestroyEffect' +++'_SDL_HapticGetEffectStatus'.'SDL2.dll'.'SDL_HapticGetEffectStatus' +++'_SDL_HapticSetGain'.'SDL2.dll'.'SDL_HapticSetGain' +++'_SDL_HapticSetAutocenter'.'SDL2.dll'.'SDL_HapticSetAutocenter' +++'_SDL_HapticPause'.'SDL2.dll'.'SDL_HapticPause' +++'_SDL_HapticUnpause'.'SDL2.dll'.'SDL_HapticUnpause' +++'_SDL_HapticStopAll'.'SDL2.dll'.'SDL_HapticStopAll' +++'_SDL_HapticRumbleSupported'.'SDL2.dll'.'SDL_HapticRumbleSupported' +++'_SDL_HapticRumbleInit'.'SDL2.dll'.'SDL_HapticRumbleInit' +++'_SDL_HapticRumblePlay'.'SDL2.dll'.'SDL_HapticRumblePlay' +++'_SDL_HapticRumbleStop'.'SDL2.dll'.'SDL_HapticRumbleStop' +++'_SDL_SetHintWithPriority'.'SDL2.dll'.'SDL_SetHintWithPriority' +++'_SDL_SetHint'.'SDL2.dll'.'SDL_SetHint' +++'_SDL_GetHint'.'SDL2.dll'.'SDL_GetHint' +++'_SDL_AddHintCallback'.'SDL2.dll'.'SDL_AddHintCallback' +++'_SDL_DelHintCallback'.'SDL2.dll'.'SDL_DelHintCallback' +++'_SDL_ClearHints'.'SDL2.dll'.'SDL_ClearHints' +++'_SDL_NumJoysticks'.'SDL2.dll'.'SDL_NumJoysticks' +++'_SDL_JoystickNameForIndex'.'SDL2.dll'.'SDL_JoystickNameForIndex' +++'_SDL_JoystickOpen'.'SDL2.dll'.'SDL_JoystickOpen' +++'_SDL_JoystickName'.'SDL2.dll'.'SDL_JoystickName' +++'_SDL_JoystickGetDeviceGUID'.'SDL2.dll'.'SDL_JoystickGetDeviceGUID' +++'_SDL_JoystickGetGUID'.'SDL2.dll'.'SDL_JoystickGetGUID' +++'_SDL_JoystickGetGUIDString'.'SDL2.dll'.'SDL_JoystickGetGUIDString' +++'_SDL_JoystickGetGUIDFromString'.'SDL2.dll'.'SDL_JoystickGetGUIDFromString' +++'_SDL_JoystickGetAttached'.'SDL2.dll'.'SDL_JoystickGetAttached' +++'_SDL_JoystickInstanceID'.'SDL2.dll'.'SDL_JoystickInstanceID' +++'_SDL_JoystickNumAxes'.'SDL2.dll'.'SDL_JoystickNumAxes' +++'_SDL_JoystickNumBalls'.'SDL2.dll'.'SDL_JoystickNumBalls' +++'_SDL_JoystickNumHats'.'SDL2.dll'.'SDL_JoystickNumHats' +++'_SDL_JoystickNumButtons'.'SDL2.dll'.'SDL_JoystickNumButtons' +++'_SDL_JoystickUpdate'.'SDL2.dll'.'SDL_JoystickUpdate' +++'_SDL_JoystickEventState'.'SDL2.dll'.'SDL_JoystickEventState' +++'_SDL_JoystickGetAxis'.'SDL2.dll'.'SDL_JoystickGetAxis' +++'_SDL_JoystickGetHat'.'SDL2.dll'.'SDL_JoystickGetHat' +++'_SDL_JoystickGetBall'.'SDL2.dll'.'SDL_JoystickGetBall' +++'_SDL_JoystickGetButton'.'SDL2.dll'.'SDL_JoystickGetButton' +++'_SDL_JoystickClose'.'SDL2.dll'.'SDL_JoystickClose' +++'_SDL_GetKeyboardFocus'.'SDL2.dll'.'SDL_GetKeyboardFocus' +++'_SDL_GetKeyboardState'.'SDL2.dll'.'SDL_GetKeyboardState' +++'_SDL_GetModState'.'SDL2.dll'.'SDL_GetModState' +++'_SDL_SetModState'.'SDL2.dll'.'SDL_SetModState' +++'_SDL_GetKeyFromScancode'.'SDL2.dll'.'SDL_GetKeyFromScancode' +++'_SDL_GetScancodeFromKey'.'SDL2.dll'.'SDL_GetScancodeFromKey' +++'_SDL_GetScancodeName'.'SDL2.dll'.'SDL_GetScancodeName' +++'_SDL_GetScancodeFromName'.'SDL2.dll'.'SDL_GetScancodeFromName' +++'_SDL_GetKeyName'.'SDL2.dll'.'SDL_GetKeyName' +++'_SDL_GetKeyFromName'.'SDL2.dll'.'SDL_GetKeyFromName' +++'_SDL_StartTextInput'.'SDL2.dll'.'SDL_StartTextInput' +++'_SDL_IsTextInputActive'.'SDL2.dll'.'SDL_IsTextInputActive' +++'_SDL_StopTextInput'.'SDL2.dll'.'SDL_StopTextInput' +++'_SDL_SetTextInputRect'.'SDL2.dll'.'SDL_SetTextInputRect' +++'_SDL_HasScreenKeyboardSupport'.'SDL2.dll'.'SDL_HasScreenKeyboardSupport' +++'_SDL_IsScreenKeyboardShown'.'SDL2.dll'.'SDL_IsScreenKeyboardShown' +++'_SDL_LoadObject'.'SDL2.dll'.'SDL_LoadObject' +++'_SDL_LoadFunction'.'SDL2.dll'.'SDL_LoadFunction' +++'_SDL_UnloadObject'.'SDL2.dll'.'SDL_UnloadObject' +++'_SDL_LogSetAllPriority'.'SDL2.dll'.'SDL_LogSetAllPriority' +++'_SDL_LogSetPriority'.'SDL2.dll'.'SDL_LogSetPriority' +++'_SDL_LogGetPriority'.'SDL2.dll'.'SDL_LogGetPriority' +++'_SDL_LogResetPriorities'.'SDL2.dll'.'SDL_LogResetPriorities' +++'_SDL_LogMessageV'.'SDL2.dll'.'SDL_LogMessageV' +++'_SDL_LogGetOutputFunction'.'SDL2.dll'.'SDL_LogGetOutputFunction' +++'_SDL_LogSetOutputFunction'.'SDL2.dll'.'SDL_LogSetOutputFunction' +++'_SDL_SetMainReady'.'SDL2.dll'.'SDL_SetMainReady' +++'_SDL_ShowMessageBox'.'SDL2.dll'.'SDL_ShowMessageBox' +++'_SDL_ShowSimpleMessageBox'.'SDL2.dll'.'SDL_ShowSimpleMessageBox' +++'_SDL_GetMouseFocus'.'SDL2.dll'.'SDL_GetMouseFocus' +++'_SDL_GetMouseState'.'SDL2.dll'.'SDL_GetMouseState' +++'_SDL_GetRelativeMouseState'.'SDL2.dll'.'SDL_GetRelativeMouseState' +++'_SDL_WarpMouseInWindow'.'SDL2.dll'.'SDL_WarpMouseInWindow' +++'_SDL_SetRelativeMouseMode'.'SDL2.dll'.'SDL_SetRelativeMouseMode' +++'_SDL_GetRelativeMouseMode'.'SDL2.dll'.'SDL_GetRelativeMouseMode' +++'_SDL_CreateCursor'.'SDL2.dll'.'SDL_CreateCursor' +++'_SDL_CreateColorCursor'.'SDL2.dll'.'SDL_CreateColorCursor' +++'_SDL_CreateSystemCursor'.'SDL2.dll'.'SDL_CreateSystemCursor' +++'_SDL_SetCursor'.'SDL2.dll'.'SDL_SetCursor' +++'_SDL_GetCursor'.'SDL2.dll'.'SDL_GetCursor' +++'_SDL_GetDefaultCursor'.'SDL2.dll'.'SDL_GetDefaultCursor' +++'_SDL_FreeCursor'.'SDL2.dll'.'SDL_FreeCursor' +++'_SDL_ShowCursor'.'SDL2.dll'.'SDL_ShowCursor' +++'_SDL_CreateMutex'.'SDL2.dll'.'SDL_CreateMutex' +++'_SDL_LockMutex'.'SDL2.dll'.'SDL_LockMutex' +++'_SDL_TryLockMutex'.'SDL2.dll'.'SDL_TryLockMutex' +++'_SDL_UnlockMutex'.'SDL2.dll'.'SDL_UnlockMutex' +++'_SDL_DestroyMutex'.'SDL2.dll'.'SDL_DestroyMutex' +++'_SDL_CreateSemaphore'.'SDL2.dll'.'SDL_CreateSemaphore' +++'_SDL_DestroySemaphore'.'SDL2.dll'.'SDL_DestroySemaphore' +++'_SDL_SemWait'.'SDL2.dll'.'SDL_SemWait' +++'_SDL_SemTryWait'.'SDL2.dll'.'SDL_SemTryWait' +++'_SDL_SemWaitTimeout'.'SDL2.dll'.'SDL_SemWaitTimeout' +++'_SDL_SemPost'.'SDL2.dll'.'SDL_SemPost' +++'_SDL_SemValue'.'SDL2.dll'.'SDL_SemValue' +++'_SDL_CreateCond'.'SDL2.dll'.'SDL_CreateCond' +++'_SDL_DestroyCond'.'SDL2.dll'.'SDL_DestroyCond' +++'_SDL_CondSignal'.'SDL2.dll'.'SDL_CondSignal' +++'_SDL_CondBroadcast'.'SDL2.dll'.'SDL_CondBroadcast' +++'_SDL_CondWait'.'SDL2.dll'.'SDL_CondWait' +++'_SDL_CondWaitTimeout'.'SDL2.dll'.'SDL_CondWaitTimeout' +++'_SDL_GetPixelFormatName'.'SDL2.dll'.'SDL_GetPixelFormatName' +++'_SDL_PixelFormatEnumToMasks'.'SDL2.dll'.'SDL_PixelFormatEnumToMasks' +++'_SDL_MasksToPixelFormatEnum'.'SDL2.dll'.'SDL_MasksToPixelFormatEnum' +++'_SDL_AllocFormat'.'SDL2.dll'.'SDL_AllocFormat' +++'_SDL_FreeFormat'.'SDL2.dll'.'SDL_FreeFormat' +++'_SDL_AllocPalette'.'SDL2.dll'.'SDL_AllocPalette' +++'_SDL_SetPixelFormatPalette'.'SDL2.dll'.'SDL_SetPixelFormatPalette' +++'_SDL_SetPaletteColors'.'SDL2.dll'.'SDL_SetPaletteColors' +++'_SDL_FreePalette'.'SDL2.dll'.'SDL_FreePalette' +++'_SDL_MapRGB'.'SDL2.dll'.'SDL_MapRGB' +++'_SDL_MapRGBA'.'SDL2.dll'.'SDL_MapRGBA' +++'_SDL_GetRGB'.'SDL2.dll'.'SDL_GetRGB' +++'_SDL_GetRGBA'.'SDL2.dll'.'SDL_GetRGBA' +++'_SDL_CalculateGammaRamp'.'SDL2.dll'.'SDL_CalculateGammaRamp' +++'_SDL_GetPlatform'.'SDL2.dll'.'SDL_GetPlatform' +++'_SDL_GetPowerInfo'.'SDL2.dll'.'SDL_GetPowerInfo' +++'_SDL_HasIntersection'.'SDL2.dll'.'SDL_HasIntersection' +++'_SDL_IntersectRect'.'SDL2.dll'.'SDL_IntersectRect' +++'_SDL_UnionRect'.'SDL2.dll'.'SDL_UnionRect' +++'_SDL_EnclosePoints'.'SDL2.dll'.'SDL_EnclosePoints' +++'_SDL_IntersectRectAndLine'.'SDL2.dll'.'SDL_IntersectRectAndLine' +++'_SDL_GetNumRenderDrivers'.'SDL2.dll'.'SDL_GetNumRenderDrivers' +++'_SDL_GetRenderDriverInfo'.'SDL2.dll'.'SDL_GetRenderDriverInfo' +++'_SDL_CreateWindowAndRenderer'.'SDL2.dll'.'SDL_CreateWindowAndRenderer' +++'_SDL_CreateRenderer'.'SDL2.dll'.'SDL_CreateRenderer' +++'_SDL_CreateSoftwareRenderer'.'SDL2.dll'.'SDL_CreateSoftwareRenderer' +++'_SDL_GetRenderer'.'SDL2.dll'.'SDL_GetRenderer' +++'_SDL_GetRendererInfo'.'SDL2.dll'.'SDL_GetRendererInfo' +++'_SDL_GetRendererOutputSize'.'SDL2.dll'.'SDL_GetRendererOutputSize' +++'_SDL_CreateTexture'.'SDL2.dll'.'SDL_CreateTexture' +++'_SDL_CreateTextureFromSurface'.'SDL2.dll'.'SDL_CreateTextureFromSurface' +++'_SDL_QueryTexture'.'SDL2.dll'.'SDL_QueryTexture' +++'_SDL_SetTextureColorMod'.'SDL2.dll'.'SDL_SetTextureColorMod' +++'_SDL_GetTextureColorMod'.'SDL2.dll'.'SDL_GetTextureColorMod' +++'_SDL_SetTextureAlphaMod'.'SDL2.dll'.'SDL_SetTextureAlphaMod' +++'_SDL_GetTextureAlphaMod'.'SDL2.dll'.'SDL_GetTextureAlphaMod' +++'_SDL_SetTextureBlendMode'.'SDL2.dll'.'SDL_SetTextureBlendMode' +++'_SDL_GetTextureBlendMode'.'SDL2.dll'.'SDL_GetTextureBlendMode' +++'_SDL_UpdateTexture'.'SDL2.dll'.'SDL_UpdateTexture' +++'_SDL_UpdateYUVTexture'.'SDL2.dll'.'SDL_UpdateYUVTexture' +++'_SDL_LockTexture'.'SDL2.dll'.'SDL_LockTexture' +++'_SDL_UnlockTexture'.'SDL2.dll'.'SDL_UnlockTexture' +++'_SDL_RenderTargetSupported'.'SDL2.dll'.'SDL_RenderTargetSupported' +++'_SDL_SetRenderTarget'.'SDL2.dll'.'SDL_SetRenderTarget' +++'_SDL_GetRenderTarget'.'SDL2.dll'.'SDL_GetRenderTarget' +++'_SDL_RenderSetLogicalSize'.'SDL2.dll'.'SDL_RenderSetLogicalSize' +++'_SDL_RenderGetLogicalSize'.'SDL2.dll'.'SDL_RenderGetLogicalSize' +++'_SDL_RenderSetViewport'.'SDL2.dll'.'SDL_RenderSetViewport' +++'_SDL_RenderGetViewport'.'SDL2.dll'.'SDL_RenderGetViewport' +++'_SDL_RenderSetClipRect'.'SDL2.dll'.'SDL_RenderSetClipRect' +++'_SDL_RenderGetClipRect'.'SDL2.dll'.'SDL_RenderGetClipRect' +++'_SDL_RenderSetScale'.'SDL2.dll'.'SDL_RenderSetScale' +++'_SDL_RenderGetScale'.'SDL2.dll'.'SDL_RenderGetScale' +++'_SDL_SetRenderDrawColor'.'SDL2.dll'.'SDL_SetRenderDrawColor' +++'_SDL_GetRenderDrawColor'.'SDL2.dll'.'SDL_GetRenderDrawColor' +++'_SDL_SetRenderDrawBlendMode'.'SDL2.dll'.'SDL_SetRenderDrawBlendMode' +++'_SDL_GetRenderDrawBlendMode'.'SDL2.dll'.'SDL_GetRenderDrawBlendMode' +++'_SDL_RenderClear'.'SDL2.dll'.'SDL_RenderClear' +++'_SDL_RenderDrawPoint'.'SDL2.dll'.'SDL_RenderDrawPoint' +++'_SDL_RenderDrawPoints'.'SDL2.dll'.'SDL_RenderDrawPoints' +++'_SDL_RenderDrawLine'.'SDL2.dll'.'SDL_RenderDrawLine' +++'_SDL_RenderDrawLines'.'SDL2.dll'.'SDL_RenderDrawLines' +++'_SDL_RenderDrawRect'.'SDL2.dll'.'SDL_RenderDrawRect' +++'_SDL_RenderDrawRects'.'SDL2.dll'.'SDL_RenderDrawRects' +++'_SDL_RenderFillRect'.'SDL2.dll'.'SDL_RenderFillRect' +++'_SDL_RenderFillRects'.'SDL2.dll'.'SDL_RenderFillRects' +++'_SDL_RenderCopy'.'SDL2.dll'.'SDL_RenderCopy' +++'_SDL_RenderCopyEx'.'SDL2.dll'.'SDL_RenderCopyEx' +++'_SDL_RenderReadPixels'.'SDL2.dll'.'SDL_RenderReadPixels' +++'_SDL_RenderPresent'.'SDL2.dll'.'SDL_RenderPresent' +++'_SDL_DestroyTexture'.'SDL2.dll'.'SDL_DestroyTexture' +++'_SDL_DestroyRenderer'.'SDL2.dll'.'SDL_DestroyRenderer' +++'_SDL_GL_BindTexture'.'SDL2.dll'.'SDL_GL_BindTexture' +++'_SDL_GL_UnbindTexture'.'SDL2.dll'.'SDL_GL_UnbindTexture' +++'_SDL_RWFromFile'.'SDL2.dll'.'SDL_RWFromFile' +++'_SDL_RWFromMem'.'SDL2.dll'.'SDL_RWFromMem' +++'_SDL_RWFromConstMem'.'SDL2.dll'.'SDL_RWFromConstMem' +++'_SDL_AllocRW'.'SDL2.dll'.'SDL_AllocRW' +++'_SDL_FreeRW'.'SDL2.dll'.'SDL_FreeRW' +++'_SDL_ReadU8'.'SDL2.dll'.'SDL_ReadU8' +++'_SDL_ReadLE16'.'SDL2.dll'.'SDL_ReadLE16' +++'_SDL_ReadBE16'.'SDL2.dll'.'SDL_ReadBE16' +++'_SDL_ReadLE32'.'SDL2.dll'.'SDL_ReadLE32' +++'_SDL_ReadBE32'.'SDL2.dll'.'SDL_ReadBE32' +++'_SDL_ReadLE64'.'SDL2.dll'.'SDL_ReadLE64' +++'_SDL_ReadBE64'.'SDL2.dll'.'SDL_ReadBE64' +++'_SDL_WriteU8'.'SDL2.dll'.'SDL_WriteU8' +++'_SDL_WriteLE16'.'SDL2.dll'.'SDL_WriteLE16' +++'_SDL_WriteBE16'.'SDL2.dll'.'SDL_WriteBE16' +++'_SDL_WriteLE32'.'SDL2.dll'.'SDL_WriteLE32' +++'_SDL_WriteBE32'.'SDL2.dll'.'SDL_WriteBE32' +++'_SDL_WriteLE64'.'SDL2.dll'.'SDL_WriteLE64' +++'_SDL_WriteBE64'.'SDL2.dll'.'SDL_WriteBE64' +++'_SDL_CreateShapedWindow'.'SDL2.dll'.'SDL_CreateShapedWindow' +++'_SDL_IsShapedWindow'.'SDL2.dll'.'SDL_IsShapedWindow' +++'_SDL_SetWindowShape'.'SDL2.dll'.'SDL_SetWindowShape' +++'_SDL_GetShapedWindowMode'.'SDL2.dll'.'SDL_GetShapedWindowMode' +++'_SDL_malloc'.'SDL2.dll'.'SDL_malloc' +++'_SDL_calloc'.'SDL2.dll'.'SDL_calloc' +++'_SDL_realloc'.'SDL2.dll'.'SDL_realloc' +++'_SDL_free'.'SDL2.dll'.'SDL_free' +++'_SDL_getenv'.'SDL2.dll'.'SDL_getenv' +++'_SDL_setenv'.'SDL2.dll'.'SDL_setenv' +++'_SDL_qsort'.'SDL2.dll'.'SDL_qsort' +++'_SDL_abs'.'SDL2.dll'.'SDL_abs' +++'_SDL_isdigit'.'SDL2.dll'.'SDL_isdigit' +++'_SDL_isspace'.'SDL2.dll'.'SDL_isspace' +++'_SDL_toupper'.'SDL2.dll'.'SDL_toupper' +++'_SDL_tolower'.'SDL2.dll'.'SDL_tolower' +++'_SDL_memset'.'SDL2.dll'.'SDL_memset' +++'_SDL_memcpy'.'SDL2.dll'.'SDL_memcpy' +++'_SDL_memmove'.'SDL2.dll'.'SDL_memmove' +++'_SDL_memcmp'.'SDL2.dll'.'SDL_memcmp' +++'_SDL_wcslen'.'SDL2.dll'.'SDL_wcslen' +++'_SDL_wcslcpy'.'SDL2.dll'.'SDL_wcslcpy' +++'_SDL_wcslcat'.'SDL2.dll'.'SDL_wcslcat' +++'_SDL_strlen'.'SDL2.dll'.'SDL_strlen' +++'_SDL_strlcpy'.'SDL2.dll'.'SDL_strlcpy' +++'_SDL_utf8strlcpy'.'SDL2.dll'.'SDL_utf8strlcpy' +++'_SDL_strlcat'.'SDL2.dll'.'SDL_strlcat' +++'_SDL_strdup'.'SDL2.dll'.'SDL_strdup' +++'_SDL_strrev'.'SDL2.dll'.'SDL_strrev' +++'_SDL_strupr'.'SDL2.dll'.'SDL_strupr' +++'_SDL_strlwr'.'SDL2.dll'.'SDL_strlwr' +++'_SDL_strchr'.'SDL2.dll'.'SDL_strchr' +++'_SDL_strrchr'.'SDL2.dll'.'SDL_strrchr' +++'_SDL_strstr'.'SDL2.dll'.'SDL_strstr' +++'_SDL_itoa'.'SDL2.dll'.'SDL_itoa' +++'_SDL_uitoa'.'SDL2.dll'.'SDL_uitoa' +++'_SDL_ltoa'.'SDL2.dll'.'SDL_ltoa' +++'_SDL_ultoa'.'SDL2.dll'.'SDL_ultoa' +++'_SDL_lltoa'.'SDL2.dll'.'SDL_lltoa' +++'_SDL_ulltoa'.'SDL2.dll'.'SDL_ulltoa' +++'_SDL_atoi'.'SDL2.dll'.'SDL_atoi' +++'_SDL_atof'.'SDL2.dll'.'SDL_atof' +++'_SDL_strtol'.'SDL2.dll'.'SDL_strtol' +++'_SDL_strtoul'.'SDL2.dll'.'SDL_strtoul' +++'_SDL_strtoll'.'SDL2.dll'.'SDL_strtoll' +++'_SDL_strtoull'.'SDL2.dll'.'SDL_strtoull' +++'_SDL_strtod'.'SDL2.dll'.'SDL_strtod' +++'_SDL_strcmp'.'SDL2.dll'.'SDL_strcmp' +++'_SDL_strncmp'.'SDL2.dll'.'SDL_strncmp' +++'_SDL_strcasecmp'.'SDL2.dll'.'SDL_strcasecmp' +++'_SDL_strncasecmp'.'SDL2.dll'.'SDL_strncasecmp' +++'_SDL_vsnprintf'.'SDL2.dll'.'SDL_vsnprintf' +++'_SDL_acos'.'SDL2.dll'.'SDL_acos' +++'_SDL_asin'.'SDL2.dll'.'SDL_asin' +++'_SDL_atan'.'SDL2.dll'.'SDL_atan' +++'_SDL_atan2'.'SDL2.dll'.'SDL_atan2' +++'_SDL_ceil'.'SDL2.dll'.'SDL_ceil' +++'_SDL_copysign'.'SDL2.dll'.'SDL_copysign' +++'_SDL_cos'.'SDL2.dll'.'SDL_cos' +++'_SDL_cosf'.'SDL2.dll'.'SDL_cosf' +++'_SDL_fabs'.'SDL2.dll'.'SDL_fabs' +++'_SDL_floor'.'SDL2.dll'.'SDL_floor' +++'_SDL_log'.'SDL2.dll'.'SDL_log' +++'_SDL_pow'.'SDL2.dll'.'SDL_pow' +++'_SDL_scalbn'.'SDL2.dll'.'SDL_scalbn' +++'_SDL_sin'.'SDL2.dll'.'SDL_sin' +++'_SDL_sinf'.'SDL2.dll'.'SDL_sinf' +++'_SDL_sqrt'.'SDL2.dll'.'SDL_sqrt' +++'_SDL_iconv_open'.'SDL2.dll'.'SDL_iconv_open' +++'_SDL_iconv_close'.'SDL2.dll'.'SDL_iconv_close' +++'_SDL_iconv'.'SDL2.dll'.'SDL_iconv' +++'_SDL_iconv_string'.'SDL2.dll'.'SDL_iconv_string' +++'_SDL_CreateRGBSurface'.'SDL2.dll'.'SDL_CreateRGBSurface' +++'_SDL_CreateRGBSurfaceFrom'.'SDL2.dll'.'SDL_CreateRGBSurfaceFrom' +++'_SDL_FreeSurface'.'SDL2.dll'.'SDL_FreeSurface' +++'_SDL_SetSurfacePalette'.'SDL2.dll'.'SDL_SetSurfacePalette' +++'_SDL_LockSurface'.'SDL2.dll'.'SDL_LockSurface' +++'_SDL_UnlockSurface'.'SDL2.dll'.'SDL_UnlockSurface' +++'_SDL_LoadBMP_RW'.'SDL2.dll'.'SDL_LoadBMP_RW' +++'_SDL_SaveBMP_RW'.'SDL2.dll'.'SDL_SaveBMP_RW' +++'_SDL_SetSurfaceRLE'.'SDL2.dll'.'SDL_SetSurfaceRLE' +++'_SDL_SetColorKey'.'SDL2.dll'.'SDL_SetColorKey' +++'_SDL_GetColorKey'.'SDL2.dll'.'SDL_GetColorKey' +++'_SDL_SetSurfaceColorMod'.'SDL2.dll'.'SDL_SetSurfaceColorMod' +++'_SDL_GetSurfaceColorMod'.'SDL2.dll'.'SDL_GetSurfaceColorMod' +++'_SDL_SetSurfaceAlphaMod'.'SDL2.dll'.'SDL_SetSurfaceAlphaMod' +++'_SDL_GetSurfaceAlphaMod'.'SDL2.dll'.'SDL_GetSurfaceAlphaMod' +++'_SDL_SetSurfaceBlendMode'.'SDL2.dll'.'SDL_SetSurfaceBlendMode' +++'_SDL_GetSurfaceBlendMode'.'SDL2.dll'.'SDL_GetSurfaceBlendMode' +++'_SDL_SetClipRect'.'SDL2.dll'.'SDL_SetClipRect' +++'_SDL_GetClipRect'.'SDL2.dll'.'SDL_GetClipRect' +++'_SDL_ConvertSurface'.'SDL2.dll'.'SDL_ConvertSurface' +++'_SDL_ConvertSurfaceFormat'.'SDL2.dll'.'SDL_ConvertSurfaceFormat' +++'_SDL_ConvertPixels'.'SDL2.dll'.'SDL_ConvertPixels' +++'_SDL_FillRect'.'SDL2.dll'.'SDL_FillRect' +++'_SDL_FillRects'.'SDL2.dll'.'SDL_FillRects' +++'_SDL_UpperBlit'.'SDL2.dll'.'SDL_UpperBlit' +++'_SDL_LowerBlit'.'SDL2.dll'.'SDL_LowerBlit' +++'_SDL_SoftStretch'.'SDL2.dll'.'SDL_SoftStretch' +++'_SDL_UpperBlitScaled'.'SDL2.dll'.'SDL_UpperBlitScaled' +++'_SDL_LowerBlitScaled'.'SDL2.dll'.'SDL_LowerBlitScaled' +++'_SDL_GetWindowWMInfo'.'SDL2.dll'.'SDL_GetWindowWMInfo' +++'_SDL_GetThreadName'.'SDL2.dll'.'SDL_GetThreadName' +++'_SDL_ThreadID'.'SDL2.dll'.'SDL_ThreadID' +++'_SDL_GetThreadID'.'SDL2.dll'.'SDL_GetThreadID' +++'_SDL_SetThreadPriority'.'SDL2.dll'.'SDL_SetThreadPriority' +++'_SDL_WaitThread'.'SDL2.dll'.'SDL_WaitThread' +++'_SDL_DetachThread'.'SDL2.dll'.'SDL_DetachThread' +++'_SDL_TLSCreate'.'SDL2.dll'.'SDL_TLSCreate' +++'_SDL_TLSGet'.'SDL2.dll'.'SDL_TLSGet' +++'_SDL_TLSSet'.'SDL2.dll'.'SDL_TLSSet' +++'_SDL_GetTicks'.'SDL2.dll'.'SDL_GetTicks' +++'_SDL_GetPerformanceCounter'.'SDL2.dll'.'SDL_GetPerformanceCounter' +++'_SDL_GetPerformanceFrequency'.'SDL2.dll'.'SDL_GetPerformanceFrequency' +++'_SDL_Delay'.'SDL2.dll'.'SDL_Delay' +++'_SDL_AddTimer'.'SDL2.dll'.'SDL_AddTimer' +++'_SDL_RemoveTimer'.'SDL2.dll'.'SDL_RemoveTimer' +++'_SDL_GetNumTouchDevices'.'SDL2.dll'.'SDL_GetNumTouchDevices' +++'_SDL_GetTouchDevice'.'SDL2.dll'.'SDL_GetTouchDevice' +++'_SDL_GetNumTouchFingers'.'SDL2.dll'.'SDL_GetNumTouchFingers' +++'_SDL_GetTouchFinger'.'SDL2.dll'.'SDL_GetTouchFinger' +++'_SDL_GetVersion'.'SDL2.dll'.'SDL_GetVersion' +++'_SDL_GetRevision'.'SDL2.dll'.'SDL_GetRevision' +++'_SDL_GetRevisionNumber'.'SDL2.dll'.'SDL_GetRevisionNumber' +++'_SDL_GetNumVideoDrivers'.'SDL2.dll'.'SDL_GetNumVideoDrivers' +++'_SDL_GetVideoDriver'.'SDL2.dll'.'SDL_GetVideoDriver' +++'_SDL_VideoInit'.'SDL2.dll'.'SDL_VideoInit' +++'_SDL_VideoQuit'.'SDL2.dll'.'SDL_VideoQuit' +++'_SDL_GetCurrentVideoDriver'.'SDL2.dll'.'SDL_GetCurrentVideoDriver' +++'_SDL_GetNumVideoDisplays'.'SDL2.dll'.'SDL_GetNumVideoDisplays' +++'_SDL_GetDisplayName'.'SDL2.dll'.'SDL_GetDisplayName' +++'_SDL_GetDisplayBounds'.'SDL2.dll'.'SDL_GetDisplayBounds' +++'_SDL_GetDisplayDPI'.'SDL2.dll'.'SDL_GetDisplayDPI' +++'_SDL_GetNumDisplayModes'.'SDL2.dll'.'SDL_GetNumDisplayModes' +++'_SDL_GetDisplayMode'.'SDL2.dll'.'SDL_GetDisplayMode' +++'_SDL_GetDesktopDisplayMode'.'SDL2.dll'.'SDL_GetDesktopDisplayMode' +++'_SDL_GetCurrentDisplayMode'.'SDL2.dll'.'SDL_GetCurrentDisplayMode' +++'_SDL_GetClosestDisplayMode'.'SDL2.dll'.'SDL_GetClosestDisplayMode' +++'_SDL_GetWindowDisplayIndex'.'SDL2.dll'.'SDL_GetWindowDisplayIndex' +++'_SDL_SetWindowDisplayMode'.'SDL2.dll'.'SDL_SetWindowDisplayMode' +++'_SDL_GetWindowDisplayMode'.'SDL2.dll'.'SDL_GetWindowDisplayMode' +++'_SDL_GetWindowPixelFormat'.'SDL2.dll'.'SDL_GetWindowPixelFormat' +++'_SDL_CreateWindow'.'SDL2.dll'.'SDL_CreateWindow' +++'_SDL_CreateWindowFrom'.'SDL2.dll'.'SDL_CreateWindowFrom' +++'_SDL_GetWindowID'.'SDL2.dll'.'SDL_GetWindowID' +++'_SDL_GetWindowFromID'.'SDL2.dll'.'SDL_GetWindowFromID' +++'_SDL_GetWindowFlags'.'SDL2.dll'.'SDL_GetWindowFlags' +++'_SDL_SetWindowTitle'.'SDL2.dll'.'SDL_SetWindowTitle' +++'_SDL_GetWindowTitle'.'SDL2.dll'.'SDL_GetWindowTitle' +++'_SDL_SetWindowIcon'.'SDL2.dll'.'SDL_SetWindowIcon' +++'_SDL_SetWindowData'.'SDL2.dll'.'SDL_SetWindowData' +++'_SDL_GetWindowData'.'SDL2.dll'.'SDL_GetWindowData' +++'_SDL_SetWindowPosition'.'SDL2.dll'.'SDL_SetWindowPosition' +++'_SDL_GetWindowPosition'.'SDL2.dll'.'SDL_GetWindowPosition' +++'_SDL_SetWindowSize'.'SDL2.dll'.'SDL_SetWindowSize' +++'_SDL_GetWindowSize'.'SDL2.dll'.'SDL_GetWindowSize' +++'_SDL_SetWindowMinimumSize'.'SDL2.dll'.'SDL_SetWindowMinimumSize' +++'_SDL_GetWindowMinimumSize'.'SDL2.dll'.'SDL_GetWindowMinimumSize' +++'_SDL_SetWindowMaximumSize'.'SDL2.dll'.'SDL_SetWindowMaximumSize' +++'_SDL_GetWindowMaximumSize'.'SDL2.dll'.'SDL_GetWindowMaximumSize' +++'_SDL_SetWindowBordered'.'SDL2.dll'.'SDL_SetWindowBordered' +++'_SDL_ShowWindow'.'SDL2.dll'.'SDL_ShowWindow' +++'_SDL_HideWindow'.'SDL2.dll'.'SDL_HideWindow' +++'_SDL_RaiseWindow'.'SDL2.dll'.'SDL_RaiseWindow' +++'_SDL_MaximizeWindow'.'SDL2.dll'.'SDL_MaximizeWindow' +++'_SDL_MinimizeWindow'.'SDL2.dll'.'SDL_MinimizeWindow' +++'_SDL_RestoreWindow'.'SDL2.dll'.'SDL_RestoreWindow' +++'_SDL_SetWindowFullscreen'.'SDL2.dll'.'SDL_SetWindowFullscreen' +++'_SDL_GetWindowSurface'.'SDL2.dll'.'SDL_GetWindowSurface' +++'_SDL_UpdateWindowSurface'.'SDL2.dll'.'SDL_UpdateWindowSurface' +++'_SDL_UpdateWindowSurfaceRects'.'SDL2.dll'.'SDL_UpdateWindowSurfaceRects' +++'_SDL_SetWindowGrab'.'SDL2.dll'.'SDL_SetWindowGrab' +++'_SDL_GetWindowGrab'.'SDL2.dll'.'SDL_GetWindowGrab' +++'_SDL_SetWindowBrightness'.'SDL2.dll'.'SDL_SetWindowBrightness' +++'_SDL_GetWindowBrightness'.'SDL2.dll'.'SDL_GetWindowBrightness' +++'_SDL_SetWindowGammaRamp'.'SDL2.dll'.'SDL_SetWindowGammaRamp' +++'_SDL_GetWindowGammaRamp'.'SDL2.dll'.'SDL_GetWindowGammaRamp' +++'_SDL_DestroyWindow'.'SDL2.dll'.'SDL_DestroyWindow' +++'_SDL_IsScreenSaverEnabled'.'SDL2.dll'.'SDL_IsScreenSaverEnabled' +++'_SDL_EnableScreenSaver'.'SDL2.dll'.'SDL_EnableScreenSaver' +++'_SDL_DisableScreenSaver'.'SDL2.dll'.'SDL_DisableScreenSaver' +++'_SDL_GL_LoadLibrary'.'SDL2.dll'.'SDL_GL_LoadLibrary' +++'_SDL_GL_GetProcAddress'.'SDL2.dll'.'SDL_GL_GetProcAddress' +++'_SDL_GL_UnloadLibrary'.'SDL2.dll'.'SDL_GL_UnloadLibrary' +++'_SDL_GL_ExtensionSupported'.'SDL2.dll'.'SDL_GL_ExtensionSupported' +++'_SDL_GL_SetAttribute'.'SDL2.dll'.'SDL_GL_SetAttribute' +++'_SDL_GL_GetAttribute'.'SDL2.dll'.'SDL_GL_GetAttribute' +++'_SDL_GL_CreateContext'.'SDL2.dll'.'SDL_GL_CreateContext' +++'_SDL_GL_MakeCurrent'.'SDL2.dll'.'SDL_GL_MakeCurrent' +++'_SDL_GL_GetCurrentWindow'.'SDL2.dll'.'SDL_GL_GetCurrentWindow' +++'_SDL_GL_GetCurrentContext'.'SDL2.dll'.'SDL_GL_GetCurrentContext' +++'_SDL_GL_GetDrawableSize'.'SDL2.dll'.'SDL_GL_GetDrawableSize' +++'_SDL_GL_SetSwapInterval'.'SDL2.dll'.'SDL_GL_SetSwapInterval' +++'_SDL_GL_GetSwapInterval'.'SDL2.dll'.'SDL_GL_GetSwapInterval' +++'_SDL_GL_SwapWindow'.'SDL2.dll'.'SDL_GL_SwapWindow' +++'_SDL_GL_DeleteContext'.'SDL2.dll'.'SDL_GL_DeleteContext' +++'_SDL_vsscanf'.'SDL2.dll'.'SDL_vsscanf' +++'_SDL_GameControllerAddMappingsFromRW'.'SDL2.dll'.'SDL_GameControllerAddMappingsFromRW' +++'_SDL_GL_ResetAttributes'.'SDL2.dll'.'SDL_GL_ResetAttributes' +++'_SDL_HasAVX'.'SDL2.dll'.'SDL_HasAVX' +++'_SDL_GetDefaultAssertionHandler'.'SDL2.dll'.'SDL_GetDefaultAssertionHandler' +++'_SDL_GetAssertionHandler'.'SDL2.dll'.'SDL_GetAssertionHandler' +++'_SDL_DXGIGetOutputInfo'.'SDL2.dll'.'SDL_DXGIGetOutputInfo' +++'_SDL_RenderIsClipEnabled'.'SDL2.dll'.'SDL_RenderIsClipEnabled' +# ++'_SDL_WinRTRunApp'.'SDL2.dll'.'SDL_WinRTRunApp' +++'_SDL_WarpMouseGlobal'.'SDL2.dll'.'SDL_WarpMouseGlobal' +# ++'_SDL_WinRTGetFSPathUNICODE'.'SDL2.dll'.'SDL_WinRTGetFSPathUNICODE' +# ++'_SDL_WinRTGetFSPathUTF8'.'SDL2.dll'.'SDL_WinRTGetFSPathUTF8' +++'_SDL_sqrtf'.'SDL2.dll'.'SDL_sqrtf' +++'_SDL_tan'.'SDL2.dll'.'SDL_tan' +++'_SDL_tanf'.'SDL2.dll'.'SDL_tanf' +++'_SDL_CaptureMouse'.'SDL2.dll'.'SDL_CaptureMouse' +++'_SDL_SetWindowHitTest'.'SDL2.dll'.'SDL_SetWindowHitTest' +++'_SDL_GetGlobalMouseState'.'SDL2.dll'.'SDL_GetGlobalMouseState' +++'_SDL_HasAVX2'.'SDL2.dll'.'SDL_HasAVX2' +++'_SDL_QueueAudio'.'SDL2.dll'.'SDL_QueueAudio' +++'_SDL_GetQueuedAudioSize'.'SDL2.dll'.'SDL_GetQueuedAudioSize' +++'_SDL_ClearQueuedAudio'.'SDL2.dll'.'SDL_ClearQueuedAudio' +++'_SDL_GetGrabbedWindow'.'SDL2.dll'.'SDL_GetGrabbedWindow' +++'_SDL_SetWindowsMessageHook'.'SDL2.dll'.'SDL_SetWindowsMessageHook' +++'_SDL_JoystickCurrentPowerLevel'.'SDL2.dll'.'SDL_JoystickCurrentPowerLevel' +++'_SDL_GameControllerFromInstanceID'.'SDL2.dll'.'SDL_GameControllerFromInstanceID' +++'_SDL_JoystickFromInstanceID'.'SDL2.dll'.'SDL_JoystickFromInstanceID' +++'_SDL_GetDisplayUsableBounds'.'SDL2.dll'.'SDL_GetDisplayUsableBounds' +++'_SDL_GetWindowBordersSize'.'SDL2.dll'.'SDL_GetWindowBordersSize' +++'_SDL_SetWindowOpacity'.'SDL2.dll'.'SDL_SetWindowOpacity' +++'_SDL_GetWindowOpacity'.'SDL2.dll'.'SDL_GetWindowOpacity' +++'_SDL_SetWindowInputFocus'.'SDL2.dll'.'SDL_SetWindowInputFocus' +++'_SDL_SetWindowModalFor'.'SDL2.dll'.'SDL_SetWindowModalFor' +++'_SDL_RenderSetIntegerScale'.'SDL2.dll'.'SDL_RenderSetIntegerScale' +++'_SDL_RenderGetIntegerScale'.'SDL2.dll'.'SDL_RenderGetIntegerScale' +++'_SDL_DequeueAudio'.'SDL2.dll'.'SDL_DequeueAudio' +++'_SDL_SetWindowResizable'.'SDL2.dll'.'SDL_SetWindowResizable' +++'_SDL_CreateRGBSurfaceWithFormat'.'SDL2.dll'.'SDL_CreateRGBSurfaceWithFormat' +++'_SDL_CreateRGBSurfaceWithFormatFrom'.'SDL2.dll'.'SDL_CreateRGBSurfaceWithFormatFrom' +++'_SDL_GetHintBoolean'.'SDL2.dll'.'SDL_GetHintBoolean' +++'_SDL_JoystickGetDeviceVendor'.'SDL2.dll'.'SDL_JoystickGetDeviceVendor' +++'_SDL_JoystickGetDeviceProduct'.'SDL2.dll'.'SDL_JoystickGetDeviceProduct' +++'_SDL_JoystickGetDeviceProductVersion'.'SDL2.dll'.'SDL_JoystickGetDeviceProductVersion' +++'_SDL_JoystickGetVendor'.'SDL2.dll'.'SDL_JoystickGetVendor' +++'_SDL_JoystickGetProduct'.'SDL2.dll'.'SDL_JoystickGetProduct' +++'_SDL_JoystickGetProductVersion'.'SDL2.dll'.'SDL_JoystickGetProductVersion' +++'_SDL_GameControllerGetVendor'.'SDL2.dll'.'SDL_GameControllerGetVendor' +++'_SDL_GameControllerGetProduct'.'SDL2.dll'.'SDL_GameControllerGetProduct' +++'_SDL_GameControllerGetProductVersion'.'SDL2.dll'.'SDL_GameControllerGetProductVersion' +++'_SDL_HasNEON'.'SDL2.dll'.'SDL_HasNEON' +++'_SDL_GameControllerNumMappings'.'SDL2.dll'.'SDL_GameControllerNumMappings' +++'_SDL_GameControllerMappingForIndex'.'SDL2.dll'.'SDL_GameControllerMappingForIndex' +++'_SDL_JoystickGetAxisInitialState'.'SDL2.dll'.'SDL_JoystickGetAxisInitialState' +++'_SDL_JoystickGetDeviceType'.'SDL2.dll'.'SDL_JoystickGetDeviceType' +++'_SDL_JoystickGetType'.'SDL2.dll'.'SDL_JoystickGetType' +++'_SDL_MemoryBarrierReleaseFunction'.'SDL2.dll'.'SDL_MemoryBarrierReleaseFunction' +++'_SDL_MemoryBarrierAcquireFunction'.'SDL2.dll'.'SDL_MemoryBarrierAcquireFunction' +++'_SDL_JoystickGetDeviceInstanceID'.'SDL2.dll'.'SDL_JoystickGetDeviceInstanceID' +++'_SDL_utf8strlen'.'SDL2.dll'.'SDL_utf8strlen' +++'_SDL_LoadFile_RW'.'SDL2.dll'.'SDL_LoadFile_RW' +++'_SDL_wcscmp'.'SDL2.dll'.'SDL_wcscmp' +++'_SDL_ComposeCustomBlendMode'.'SDL2.dll'.'SDL_ComposeCustomBlendMode' +++'_SDL_DuplicateSurface'.'SDL2.dll'.'SDL_DuplicateSurface' +++'_SDL_Vulkan_LoadLibrary'.'SDL2.dll'.'SDL_Vulkan_LoadLibrary' +++'_SDL_Vulkan_GetVkGetInstanceProcAddr'.'SDL2.dll'.'SDL_Vulkan_GetVkGetInstanceProcAddr' +++'_SDL_Vulkan_UnloadLibrary'.'SDL2.dll'.'SDL_Vulkan_UnloadLibrary' +++'_SDL_Vulkan_GetInstanceExtensions'.'SDL2.dll'.'SDL_Vulkan_GetInstanceExtensions' +++'_SDL_Vulkan_CreateSurface'.'SDL2.dll'.'SDL_Vulkan_CreateSurface' +++'_SDL_Vulkan_GetDrawableSize'.'SDL2.dll'.'SDL_Vulkan_GetDrawableSize' +++'_SDL_LockJoysticks'.'SDL2.dll'.'SDL_LockJoysticks' +++'_SDL_UnlockJoysticks'.'SDL2.dll'.'SDL_UnlockJoysticks' +++'_SDL_GetMemoryFunctions'.'SDL2.dll'.'SDL_GetMemoryFunctions' +++'_SDL_SetMemoryFunctions'.'SDL2.dll'.'SDL_SetMemoryFunctions' +++'_SDL_GetNumAllocations'.'SDL2.dll'.'SDL_GetNumAllocations' +++'_SDL_NewAudioStream'.'SDL2.dll'.'SDL_NewAudioStream' +++'_SDL_AudioStreamPut'.'SDL2.dll'.'SDL_AudioStreamPut' +++'_SDL_AudioStreamGet'.'SDL2.dll'.'SDL_AudioStreamGet' +++'_SDL_AudioStreamClear'.'SDL2.dll'.'SDL_AudioStreamClear' +++'_SDL_AudioStreamAvailable'.'SDL2.dll'.'SDL_AudioStreamAvailable' +++'_SDL_FreeAudioStream'.'SDL2.dll'.'SDL_FreeAudioStream' +++'_SDL_AudioStreamFlush'.'SDL2.dll'.'SDL_AudioStreamFlush' +++'_SDL_acosf'.'SDL2.dll'.'SDL_acosf' +++'_SDL_asinf'.'SDL2.dll'.'SDL_asinf' +++'_SDL_atanf'.'SDL2.dll'.'SDL_atanf' +++'_SDL_atan2f'.'SDL2.dll'.'SDL_atan2f' +++'_SDL_ceilf'.'SDL2.dll'.'SDL_ceilf' +++'_SDL_copysignf'.'SDL2.dll'.'SDL_copysignf' +++'_SDL_fabsf'.'SDL2.dll'.'SDL_fabsf' +++'_SDL_floorf'.'SDL2.dll'.'SDL_floorf' +++'_SDL_logf'.'SDL2.dll'.'SDL_logf' +++'_SDL_powf'.'SDL2.dll'.'SDL_powf' +++'_SDL_scalbnf'.'SDL2.dll'.'SDL_scalbnf' +++'_SDL_fmod'.'SDL2.dll'.'SDL_fmod' +++'_SDL_fmodf'.'SDL2.dll'.'SDL_fmodf' +++'_SDL_SetYUVConversionMode'.'SDL2.dll'.'SDL_SetYUVConversionMode' +++'_SDL_GetYUVConversionMode'.'SDL2.dll'.'SDL_GetYUVConversionMode' +++'_SDL_GetYUVConversionModeForResolution'.'SDL2.dll'.'SDL_GetYUVConversionModeForResolution' +++'_SDL_RenderGetMetalLayer'.'SDL2.dll'.'SDL_RenderGetMetalLayer' +++'_SDL_RenderGetMetalCommandEncoder'.'SDL2.dll'.'SDL_RenderGetMetalCommandEncoder' +# ++'_SDL_IsAndroidTV'.'SDL2.dll'.'SDL_IsAndroidTV' +# ++'_SDL_WinRTGetDeviceFamily'.'SDL2.dll'.'SDL_WinRTGetDeviceFamily' +++'_SDL_log10'.'SDL2.dll'.'SDL_log10' +++'_SDL_log10f'.'SDL2.dll'.'SDL_log10f' +++'_SDL_GameControllerMappingForDeviceIndex'.'SDL2.dll'.'SDL_GameControllerMappingForDeviceIndex' +# ++'_SDL_LinuxSetThreadPriority'.'SDL2.dll'.'SDL_LinuxSetThreadPriority' +++'_SDL_HasAVX512F'.'SDL2.dll'.'SDL_HasAVX512F' +# ++'_SDL_IsChromebook'.'SDL2.dll'.'SDL_IsChromebook' +# ++'_SDL_IsDeXMode'.'SDL2.dll'.'SDL_IsDeXMode' +# ++'_SDL_AndroidBackButton'.'SDL2.dll'.'SDL_AndroidBackButton' +++'_SDL_exp'.'SDL2.dll'.'SDL_exp' +++'_SDL_expf'.'SDL2.dll'.'SDL_expf' +++'_SDL_wcsdup'.'SDL2.dll'.'SDL_wcsdup' +++'_SDL_GameControllerRumble'.'SDL2.dll'.'SDL_GameControllerRumble' +++'_SDL_JoystickRumble'.'SDL2.dll'.'SDL_JoystickRumble' +++'_SDL_NumSensors'.'SDL2.dll'.'SDL_NumSensors' +++'_SDL_SensorGetDeviceName'.'SDL2.dll'.'SDL_SensorGetDeviceName' +++'_SDL_SensorGetDeviceType'.'SDL2.dll'.'SDL_SensorGetDeviceType' +++'_SDL_SensorGetDeviceNonPortableType'.'SDL2.dll'.'SDL_SensorGetDeviceNonPortableType' +++'_SDL_SensorGetDeviceInstanceID'.'SDL2.dll'.'SDL_SensorGetDeviceInstanceID' +++'_SDL_SensorOpen'.'SDL2.dll'.'SDL_SensorOpen' +++'_SDL_SensorFromInstanceID'.'SDL2.dll'.'SDL_SensorFromInstanceID' +++'_SDL_SensorGetName'.'SDL2.dll'.'SDL_SensorGetName' +++'_SDL_SensorGetType'.'SDL2.dll'.'SDL_SensorGetType' +++'_SDL_SensorGetNonPortableType'.'SDL2.dll'.'SDL_SensorGetNonPortableType' +++'_SDL_SensorGetInstanceID'.'SDL2.dll'.'SDL_SensorGetInstanceID' +++'_SDL_SensorGetData'.'SDL2.dll'.'SDL_SensorGetData' +++'_SDL_SensorClose'.'SDL2.dll'.'SDL_SensorClose' +++'_SDL_SensorUpdate'.'SDL2.dll'.'SDL_SensorUpdate' +++'_SDL_IsTablet'.'SDL2.dll'.'SDL_IsTablet' +++'_SDL_GetDisplayOrientation'.'SDL2.dll'.'SDL_GetDisplayOrientation' +++'_SDL_HasColorKey'.'SDL2.dll'.'SDL_HasColorKey' +++'_SDL_CreateThreadWithStackSize'.'SDL2.dll'.'SDL_CreateThreadWithStackSize' +++'_SDL_JoystickGetDevicePlayerIndex'.'SDL2.dll'.'SDL_JoystickGetDevicePlayerIndex' +++'_SDL_JoystickGetPlayerIndex'.'SDL2.dll'.'SDL_JoystickGetPlayerIndex' +++'_SDL_GameControllerGetPlayerIndex'.'SDL2.dll'.'SDL_GameControllerGetPlayerIndex' +++'_SDL_RenderFlush'.'SDL2.dll'.'SDL_RenderFlush' +++'_SDL_RenderDrawPointF'.'SDL2.dll'.'SDL_RenderDrawPointF' +++'_SDL_RenderDrawPointsF'.'SDL2.dll'.'SDL_RenderDrawPointsF' +++'_SDL_RenderDrawLineF'.'SDL2.dll'.'SDL_RenderDrawLineF' +++'_SDL_RenderDrawLinesF'.'SDL2.dll'.'SDL_RenderDrawLinesF' +++'_SDL_RenderDrawRectF'.'SDL2.dll'.'SDL_RenderDrawRectF' +++'_SDL_RenderDrawRectsF'.'SDL2.dll'.'SDL_RenderDrawRectsF' +++'_SDL_RenderFillRectF'.'SDL2.dll'.'SDL_RenderFillRectF' +++'_SDL_RenderFillRectsF'.'SDL2.dll'.'SDL_RenderFillRectsF' +++'_SDL_RenderCopyF'.'SDL2.dll'.'SDL_RenderCopyF' +++'_SDL_RenderCopyExF'.'SDL2.dll'.'SDL_RenderCopyExF' +++'_SDL_GetTouchDeviceType'.'SDL2.dll'.'SDL_GetTouchDeviceType' +# ++'_SDL_UIKitRunApp'.'SDL2.dll'.'SDL_UIKitRunApp' +++'_SDL_SIMDGetAlignment'.'SDL2.dll'.'SDL_SIMDGetAlignment' +++'_SDL_SIMDAlloc'.'SDL2.dll'.'SDL_SIMDAlloc' +++'_SDL_SIMDFree'.'SDL2.dll'.'SDL_SIMDFree' +++'_SDL_RWsize'.'SDL2.dll'.'SDL_RWsize' +++'_SDL_RWseek'.'SDL2.dll'.'SDL_RWseek' +++'_SDL_RWtell'.'SDL2.dll'.'SDL_RWtell' +++'_SDL_RWread'.'SDL2.dll'.'SDL_RWread' +++'_SDL_RWwrite'.'SDL2.dll'.'SDL_RWwrite' +++'_SDL_RWclose'.'SDL2.dll'.'SDL_RWclose' +++'_SDL_LoadFile'.'SDL2.dll'.'SDL_LoadFile' +++'_SDL_Metal_CreateView'.'SDL2.dll'.'SDL_Metal_CreateView' +++'_SDL_Metal_DestroyView'.'SDL2.dll'.'SDL_Metal_DestroyView' +++'_SDL_LockTextureToSurface'.'SDL2.dll'.'SDL_LockTextureToSurface' +++'_SDL_HasARMSIMD'.'SDL2.dll'.'SDL_HasARMSIMD' +++'_SDL_strtokr'.'SDL2.dll'.'SDL_strtokr' +++'_SDL_wcsstr'.'SDL2.dll'.'SDL_wcsstr' +++'_SDL_wcsncmp'.'SDL2.dll'.'SDL_wcsncmp' +++'_SDL_GameControllerTypeForIndex'.'SDL2.dll'.'SDL_GameControllerTypeForIndex' +++'_SDL_GameControllerGetType'.'SDL2.dll'.'SDL_GameControllerGetType' +++'_SDL_GameControllerFromPlayerIndex'.'SDL2.dll'.'SDL_GameControllerFromPlayerIndex' +++'_SDL_GameControllerSetPlayerIndex'.'SDL2.dll'.'SDL_GameControllerSetPlayerIndex' +++'_SDL_JoystickFromPlayerIndex'.'SDL2.dll'.'SDL_JoystickFromPlayerIndex' +++'_SDL_JoystickSetPlayerIndex'.'SDL2.dll'.'SDL_JoystickSetPlayerIndex' +++'_SDL_SetTextureScaleMode'.'SDL2.dll'.'SDL_SetTextureScaleMode' +++'_SDL_GetTextureScaleMode'.'SDL2.dll'.'SDL_GetTextureScaleMode' +++'_SDL_OnApplicationWillTerminate'.'SDL2.dll'.'SDL_OnApplicationWillTerminate' +++'_SDL_OnApplicationDidReceiveMemoryWarning'.'SDL2.dll'.'SDL_OnApplicationDidReceiveMemoryWarning' +++'_SDL_OnApplicationWillResignActive'.'SDL2.dll'.'SDL_OnApplicationWillResignActive' +++'_SDL_OnApplicationDidEnterBackground'.'SDL2.dll'.'SDL_OnApplicationDidEnterBackground' +++'_SDL_OnApplicationWillEnterForeground'.'SDL2.dll'.'SDL_OnApplicationWillEnterForeground' +++'_SDL_OnApplicationDidBecomeActive'.'SDL2.dll'.'SDL_OnApplicationDidBecomeActive' +# ++'_SDL_OnApplicationDidChangeStatusBarOrientation'.'SDL2.dll'.'SDL_OnApplicationDidChangeStatusBarOrientation' +# ++'_SDL_GetAndroidSDKVersion'.'SDL2.dll'.'SDL_GetAndroidSDKVersion' +++'_SDL_isupper'.'SDL2.dll'.'SDL_isupper' +++'_SDL_islower'.'SDL2.dll'.'SDL_islower' +++'_SDL_JoystickAttachVirtual'.'SDL2.dll'.'SDL_JoystickAttachVirtual' +++'_SDL_JoystickDetachVirtual'.'SDL2.dll'.'SDL_JoystickDetachVirtual' +++'_SDL_JoystickIsVirtual'.'SDL2.dll'.'SDL_JoystickIsVirtual' +++'_SDL_JoystickSetVirtualAxis'.'SDL2.dll'.'SDL_JoystickSetVirtualAxis' +++'_SDL_JoystickSetVirtualButton'.'SDL2.dll'.'SDL_JoystickSetVirtualButton' +++'_SDL_JoystickSetVirtualHat'.'SDL2.dll'.'SDL_JoystickSetVirtualHat' +++'_SDL_GetErrorMsg'.'SDL2.dll'.'SDL_GetErrorMsg' +++'_SDL_LockSensors'.'SDL2.dll'.'SDL_LockSensors' +++'_SDL_UnlockSensors'.'SDL2.dll'.'SDL_UnlockSensors' +++'_SDL_Metal_GetLayer'.'SDL2.dll'.'SDL_Metal_GetLayer' +++'_SDL_Metal_GetDrawableSize'.'SDL2.dll'.'SDL_Metal_GetDrawableSize' +++'_SDL_trunc'.'SDL2.dll'.'SDL_trunc' +++'_SDL_truncf'.'SDL2.dll'.'SDL_truncf' +++'_SDL_GetPreferredLocales'.'SDL2.dll'.'SDL_GetPreferredLocales' +++'_SDL_SIMDRealloc'.'SDL2.dll'.'SDL_SIMDRealloc' +# ++'_SDL_AndroidRequestPermission'.'SDL2.dll'.'SDL_AndroidRequestPermission' +++'_SDL_OpenURL'.'SDL2.dll'.'SDL_OpenURL' +++'_SDL_HasSurfaceRLE'.'SDL2.dll'.'SDL_HasSurfaceRLE' +++'_SDL_GameControllerHasLED'.'SDL2.dll'.'SDL_GameControllerHasLED' +++'_SDL_GameControllerSetLED'.'SDL2.dll'.'SDL_GameControllerSetLED' +++'_SDL_JoystickHasLED'.'SDL2.dll'.'SDL_JoystickHasLED' +++'_SDL_JoystickSetLED'.'SDL2.dll'.'SDL_JoystickSetLED' +++'_SDL_GameControllerRumbleTriggers'.'SDL2.dll'.'SDL_GameControllerRumbleTriggers' +++'_SDL_JoystickRumbleTriggers'.'SDL2.dll'.'SDL_JoystickRumbleTriggers' +++'_SDL_GameControllerHasAxis'.'SDL2.dll'.'SDL_GameControllerHasAxis' +++'_SDL_GameControllerHasButton'.'SDL2.dll'.'SDL_GameControllerHasButton' +++'_SDL_GameControllerGetNumTouchpads'.'SDL2.dll'.'SDL_GameControllerGetNumTouchpads' +++'_SDL_GameControllerGetNumTouchpadFingers'.'SDL2.dll'.'SDL_GameControllerGetNumTouchpadFingers' +++'_SDL_GameControllerGetTouchpadFinger'.'SDL2.dll'.'SDL_GameControllerGetTouchpadFinger' +++'_SDL_crc32'.'SDL2.dll'.'SDL_crc32' +++'_SDL_GameControllerGetSerial'.'SDL2.dll'.'SDL_GameControllerGetSerial' +++'_SDL_JoystickGetSerial'.'SDL2.dll'.'SDL_JoystickGetSerial' +++'_SDL_GameControllerHasSensor'.'SDL2.dll'.'SDL_GameControllerHasSensor' +++'_SDL_GameControllerSetSensorEnabled'.'SDL2.dll'.'SDL_GameControllerSetSensorEnabled' +++'_SDL_GameControllerIsSensorEnabled'.'SDL2.dll'.'SDL_GameControllerIsSensorEnabled' +++'_SDL_GameControllerGetSensorData'.'SDL2.dll'.'SDL_GameControllerGetSensorData' +++'_SDL_wcscasecmp'.'SDL2.dll'.'SDL_wcscasecmp' +++'_SDL_wcsncasecmp'.'SDL2.dll'.'SDL_wcsncasecmp' +++'_SDL_round'.'SDL2.dll'.'SDL_round' +++'_SDL_roundf'.'SDL2.dll'.'SDL_roundf' +++'_SDL_lround'.'SDL2.dll'.'SDL_lround' +++'_SDL_lroundf'.'SDL2.dll'.'SDL_lroundf' +++'_SDL_SoftStretchLinear'.'SDL2.dll'.'SDL_SoftStretchLinear' +++'_SDL_RenderGetD3D11Device'.'SDL2.dll'.'SDL_RenderGetD3D11Device' +++'_SDL_UpdateNVTexture'.'SDL2.dll'.'SDL_UpdateNVTexture' +++'_SDL_SetWindowKeyboardGrab'.'SDL2.dll'.'SDL_SetWindowKeyboardGrab' +++'_SDL_SetWindowMouseGrab'.'SDL2.dll'.'SDL_SetWindowMouseGrab' +++'_SDL_GetWindowKeyboardGrab'.'SDL2.dll'.'SDL_GetWindowKeyboardGrab' +++'_SDL_GetWindowMouseGrab'.'SDL2.dll'.'SDL_GetWindowMouseGrab' +++'_SDL_isalpha'.'SDL2.dll'.'SDL_isalpha' +++'_SDL_isalnum'.'SDL2.dll'.'SDL_isalnum' +++'_SDL_isblank'.'SDL2.dll'.'SDL_isblank' +++'_SDL_iscntrl'.'SDL2.dll'.'SDL_iscntrl' +++'_SDL_isxdigit'.'SDL2.dll'.'SDL_isxdigit' +++'_SDL_ispunct'.'SDL2.dll'.'SDL_ispunct' +++'_SDL_isprint'.'SDL2.dll'.'SDL_isprint' +++'_SDL_isgraph'.'SDL2.dll'.'SDL_isgraph' +# ++'_SDL_AndroidShowToast'.'SDL2.dll'.'SDL_AndroidShowToast' +++'_SDL_GetAudioDeviceSpec'.'SDL2.dll'.'SDL_GetAudioDeviceSpec' +++'_SDL_TLSCleanup'.'SDL2.dll'.'SDL_TLSCleanup' +++'_SDL_SetWindowAlwaysOnTop'.'SDL2.dll'.'SDL_SetWindowAlwaysOnTop' +++'_SDL_FlashWindow'.'SDL2.dll'.'SDL_FlashWindow' +++'_SDL_GameControllerSendEffect'.'SDL2.dll'.'SDL_GameControllerSendEffect' +++'_SDL_JoystickSendEffect'.'SDL2.dll'.'SDL_JoystickSendEffect' +++'_SDL_GameControllerGetSensorDataRate'.'SDL2.dll'.'SDL_GameControllerGetSensorDataRate' +++'_SDL_SetTextureUserData'.'SDL2.dll'.'SDL_SetTextureUserData' +++'_SDL_GetTextureUserData'.'SDL2.dll'.'SDL_GetTextureUserData' +++'_SDL_RenderGeometry'.'SDL2.dll'.'SDL_RenderGeometry' +++'_SDL_RenderGeometryRaw'.'SDL2.dll'.'SDL_RenderGeometryRaw' +++'_SDL_RenderSetVSync'.'SDL2.dll'.'SDL_RenderSetVSync' +++'_SDL_asprintf'.'SDL2.dll'.'SDL_asprintf' +++'_SDL_vasprintf'.'SDL2.dll'.'SDL_vasprintf' +++'_SDL_GetWindowICCProfile'.'SDL2.dll'.'SDL_GetWindowICCProfile' +++'_SDL_GetTicks64'.'SDL2.dll'.'SDL_GetTicks64' +# ++'_SDL_LinuxSetThreadPriorityAndPolicy'.'SDL2.dll'.'SDL_LinuxSetThreadPriorityAndPolicy' +++'_SDL_GameControllerGetAppleSFSymbolsNameForButton'.'SDL2.dll'.'SDL_GameControllerGetAppleSFSymbolsNameForButton' +++'_SDL_GameControllerGetAppleSFSymbolsNameForAxis'.'SDL2.dll'.'SDL_GameControllerGetAppleSFSymbolsNameForAxis' +++'_SDL_hid_init'.'SDL2.dll'.'SDL_hid_init' +++'_SDL_hid_exit'.'SDL2.dll'.'SDL_hid_exit' +++'_SDL_hid_device_change_count'.'SDL2.dll'.'SDL_hid_device_change_count' +++'_SDL_hid_enumerate'.'SDL2.dll'.'SDL_hid_enumerate' +++'_SDL_hid_free_enumeration'.'SDL2.dll'.'SDL_hid_free_enumeration' +++'_SDL_hid_open'.'SDL2.dll'.'SDL_hid_open' +++'_SDL_hid_open_path'.'SDL2.dll'.'SDL_hid_open_path' +++'_SDL_hid_write'.'SDL2.dll'.'SDL_hid_write' +++'_SDL_hid_read_timeout'.'SDL2.dll'.'SDL_hid_read_timeout' +++'_SDL_hid_read'.'SDL2.dll'.'SDL_hid_read' +++'_SDL_hid_set_nonblocking'.'SDL2.dll'.'SDL_hid_set_nonblocking' +++'_SDL_hid_send_feature_report'.'SDL2.dll'.'SDL_hid_send_feature_report' +++'_SDL_hid_get_feature_report'.'SDL2.dll'.'SDL_hid_get_feature_report' +++'_SDL_hid_close'.'SDL2.dll'.'SDL_hid_close' +++'_SDL_hid_get_manufacturer_string'.'SDL2.dll'.'SDL_hid_get_manufacturer_string' +++'_SDL_hid_get_product_string'.'SDL2.dll'.'SDL_hid_get_product_string' +++'_SDL_hid_get_serial_number_string'.'SDL2.dll'.'SDL_hid_get_serial_number_string' +++'_SDL_hid_get_indexed_string'.'SDL2.dll'.'SDL_hid_get_indexed_string' +++'_SDL_SetWindowMouseRect'.'SDL2.dll'.'SDL_SetWindowMouseRect' +++'_SDL_GetWindowMouseRect'.'SDL2.dll'.'SDL_GetWindowMouseRect' +++'_SDL_RenderWindowToLogical'.'SDL2.dll'.'SDL_RenderWindowToLogical' +++'_SDL_RenderLogicalToWindow'.'SDL2.dll'.'SDL_RenderLogicalToWindow' +++'_SDL_JoystickHasRumble'.'SDL2.dll'.'SDL_JoystickHasRumble' +++'_SDL_JoystickHasRumbleTriggers'.'SDL2.dll'.'SDL_JoystickHasRumbleTriggers' +++'_SDL_GameControllerHasRumble'.'SDL2.dll'.'SDL_GameControllerHasRumble' +++'_SDL_GameControllerHasRumbleTriggers'.'SDL2.dll'.'SDL_GameControllerHasRumbleTriggers' +++'_SDL_hid_ble_scan'.'SDL2.dll'.'SDL_hid_ble_scan' +++'_SDL_PremultiplyAlpha'.'SDL2.dll'.'SDL_PremultiplyAlpha' +# ++'_SDL_AndroidSendMessage'.'SDL2.dll'.'SDL_AndroidSendMessage' +++'_SDL_GetTouchName'.'SDL2.dll'.'SDL_GetTouchName' +++'_SDL_ClearComposition'.'SDL2.dll'.'SDL_ClearComposition' +++'_SDL_IsTextInputShown'.'SDL2.dll'.'SDL_IsTextInputShown' +++'_SDL_HasIntersectionF'.'SDL2.dll'.'SDL_HasIntersectionF' +++'_SDL_IntersectFRect'.'SDL2.dll'.'SDL_IntersectFRect' +++'_SDL_UnionFRect'.'SDL2.dll'.'SDL_UnionFRect' +++'_SDL_EncloseFPoints'.'SDL2.dll'.'SDL_EncloseFPoints' +++'_SDL_IntersectFRectAndLine'.'SDL2.dll'.'SDL_IntersectFRectAndLine' +++'_SDL_RenderGetWindow'.'SDL2.dll'.'SDL_RenderGetWindow' +++'_SDL_bsearch'.'SDL2.dll'.'SDL_bsearch' +++'_SDL_GameControllerPathForIndex'.'SDL2.dll'.'SDL_GameControllerPathForIndex' +++'_SDL_GameControllerPath'.'SDL2.dll'.'SDL_GameControllerPath' +++'_SDL_JoystickPathForIndex'.'SDL2.dll'.'SDL_JoystickPathForIndex' +++'_SDL_JoystickPath'.'SDL2.dll'.'SDL_JoystickPath' +++'_SDL_JoystickAttachVirtualEx'.'SDL2.dll'.'SDL_JoystickAttachVirtualEx' diff --git a/src/dynapi/SDL_dynapi.h b/src/dynapi/SDL_dynapi.h index 3dafd523b..27eeed00e 100644 --- a/src/dynapi/SDL_dynapi.h +++ b/src/dynapi/SDL_dynapi.h @@ -59,8 +59,8 @@ #define SDL_DYNAMIC_API 0 /* Turn off for static analysis, so reports are more clear. */ #elif defined(__VITA__) #define SDL_DYNAMIC_API 0 /* vitasdk doesn't support dynamic linking */ -#elif defined(__OS2__) -#define SDL_DYNAMIC_API 0 /* see github bugs #5667 and #5669 */ +#elif defined(__NGAGE__) +#define SDL_DYNAMIC_API 0 /* The N-Gage doesn't support dynamic linking either */ #elif defined(DYNAPI_NEEDS_DLOPEN) && !defined(HAVE_DLOPEN) #define SDL_DYNAMIC_API 0 /* we need dlopen(), but don't have it.... */ #elif defined(__SWITCH__) && __SWITCH__ diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 526513ad5..c756c3841 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -439,8 +439,6 @@ #define SDL_iconv_close SDL_iconv_close_REAL #define SDL_iconv SDL_iconv_REAL #define SDL_iconv_string SDL_iconv_string_REAL -#define SDL_CreateRGBSurfaceWithFormat SDL_CreateRGBSurfaceWithFormat_REAL -#define SDL_CreateRGBSurfaceWithFormatFrom SDL_CreateRGBSurfaceWithFormatFrom_REAL #define SDL_CreateRGBSurface SDL_CreateRGBSurface_REAL #define SDL_CreateRGBSurfaceFrom SDL_CreateRGBSurfaceFrom_REAL #define SDL_FreeSurface SDL_FreeSurface_REAL @@ -577,7 +575,6 @@ #define SDL_WarpMouseGlobal SDL_WarpMouseGlobal_REAL #define SDL_WinRTGetFSPathUNICODE SDL_WinRTGetFSPathUNICODE_REAL #define SDL_WinRTGetFSPathUTF8 SDL_WinRTGetFSPathUTF8_REAL -#define SDL_WinRTRunApp SDL_WinRTRunApp_REAL #define SDL_sqrtf SDL_sqrtf_REAL #define SDL_tan SDL_tan_REAL #define SDL_tanf SDL_tanf_REAL @@ -753,7 +750,6 @@ #define SDL_JoystickDetachVirtual SDL_JoystickDetachVirtual_REAL #define SDL_JoystickIsVirtual SDL_JoystickIsVirtual_REAL #define SDL_JoystickSetVirtualAxis SDL_JoystickSetVirtualAxis_REAL -#define SDL_JoystickSetVirtualBall SDL_JoystickSetVirtualBall_REAL #define SDL_JoystickSetVirtualButton SDL_JoystickSetVirtualButton_REAL #define SDL_JoystickSetVirtualHat SDL_JoystickSetVirtualHat_REAL #define SDL_GetErrorMsg SDL_GetErrorMsg_REAL @@ -865,3 +861,9 @@ #define SDL_EncloseFPoints SDL_EncloseFPoints_REAL #define SDL_IntersectFRectAndLine SDL_IntersectFRectAndLine_REAL #define SDL_RenderGetWindow SDL_RenderGetWindow_REAL +#define SDL_bsearch SDL_bsearch_REAL +#define SDL_GameControllerPathForIndex SDL_GameControllerPathForIndex_REAL +#define SDL_GameControllerPath SDL_GameControllerPath_REAL +#define SDL_JoystickPathForIndex SDL_JoystickPathForIndex_REAL +#define SDL_JoystickPath SDL_JoystickPath_REAL +#define SDL_JoystickAttachVirtualEx SDL_JoystickAttachVirtualEx_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 22bf870d9..c14e7a15f 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -70,7 +70,7 @@ SDL_DYNAPI_PROC(IDirect3DDevice9*,SDL_RenderGetD3D9Device,(SDL_Renderer *a),(a), #endif #ifdef __IPHONEOS__ -SDL_DYNAPI_PROC(int,SDL_iPhoneSetAnimationCallback,(SDL_Window *a, int b, void c, void *d),(a,b,c,d),return) +SDL_DYNAPI_PROC(int,SDL_iPhoneSetAnimationCallback,(SDL_Window *a, int b, void (SDLCALL *c)(void *), void *d),(a,b,c,d),return) SDL_DYNAPI_PROC(void,SDL_iPhoneSetEventPump,(SDL_bool a),(a),) #endif @@ -408,7 +408,7 @@ SDL_DYNAPI_PROC(void*,SDL_realloc,(void *a, size_t b),(a,b),return) SDL_DYNAPI_PROC(void,SDL_free,(void *a),(a),) SDL_DYNAPI_PROC(char*,SDL_getenv,(const char *a),(a),return) SDL_DYNAPI_PROC(int,SDL_setenv,(const char *a, const char *b, int c),(a,b,c),return) -SDL_DYNAPI_PROC(void,SDL_qsort,(void *a, size_t b, size_t c, int (*d)(const void *, const void *)),(a,b,c,d),) +SDL_DYNAPI_PROC(void,SDL_qsort,(void *a, size_t b, size_t c, int (SDLCALL *d)(const void *, const void *)),(a,b,c,d),) SDL_DYNAPI_PROC(int,SDL_abs,(int a),(a),return) SDL_DYNAPI_PROC(int,SDL_isdigit,(int a),(a),return) SDL_DYNAPI_PROC(int,SDL_isspace,(int a),(a),return) @@ -508,7 +508,7 @@ SDL_DYNAPI_PROC(void,SDL_WaitThread,(SDL_Thread *a, int *b),(a,b),) SDL_DYNAPI_PROC(void,SDL_DetachThread,(SDL_Thread *a),(a),) SDL_DYNAPI_PROC(SDL_TLSID,SDL_TLSCreate,(void),(),return) SDL_DYNAPI_PROC(void*,SDL_TLSGet,(SDL_TLSID a),(a),return) -SDL_DYNAPI_PROC(int,SDL_TLSSet,(SDL_TLSID a, const void *b, void (*c)(void*)),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_TLSSet,(SDL_TLSID a, const void *b, void (SDLCALL *c)(void*)),(a,b,c),return) SDL_DYNAPI_PROC(Uint32,SDL_GetTicks,(void),(),return) SDL_DYNAPI_PROC(Uint64,SDL_GetPerformanceCounter,(void),(),return) SDL_DYNAPI_PROC(Uint64,SDL_GetPerformanceFrequency,(void),(),return) @@ -936,3 +936,9 @@ SDL_DYNAPI_PROC(void,SDL_UnionFRect,(const SDL_FRect *a, const SDL_FRect *b, SDL 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) +SDL_DYNAPI_PROC(void*,SDL_bsearch,(const void *a, const void *b, size_t c, size_t d, int (SDLCALL *e)(const void *, const void *)),(a,b,c,d,e),return) +SDL_DYNAPI_PROC(const char*,SDL_GameControllerPathForIndex,(int a),(a),return) +SDL_DYNAPI_PROC(const char*,SDL_GameControllerPath,(SDL_GameController *a),(a),return) +SDL_DYNAPI_PROC(const char*,SDL_JoystickPathForIndex,(int a),(a),return) +SDL_DYNAPI_PROC(const char*,SDL_JoystickPath,(SDL_Joystick *a),(a),return) +SDL_DYNAPI_PROC(int,SDL_JoystickAttachVirtualEx,(const SDL_VirtualJoystickDesc *a),(a),return) diff --git a/src/dynapi/gendynapi.pl b/src/dynapi/gendynapi.pl index b99a8a492..a9ff9723b 100755 --- a/src/dynapi/gendynapi.pl +++ b/src/dynapi/gendynapi.pl @@ -33,6 +33,7 @@ use File::Basename; chdir(dirname(__FILE__) . '/../..'); my $sdl_dynapi_procs_h = "src/dynapi/SDL_dynapi_procs.h"; my $sdl_dynapi_overrides_h = "src/dynapi/SDL_dynapi_overrides.h"; +my $sdl2_exports = "src/dynapi/SDL2.exports"; my %existing = (); if (-f $sdl_dynapi_procs_h) { @@ -47,6 +48,7 @@ if (-f $sdl_dynapi_procs_h) { open(SDL_DYNAPI_PROCS_H, '>>', $sdl_dynapi_procs_h) or die("Can't open $sdl_dynapi_procs_h: $!\n"); open(SDL_DYNAPI_OVERRIDES_H, '>>', $sdl_dynapi_overrides_h) or die("Can't open $sdl_dynapi_overrides_h: $!\n"); +open(SDL2_EXPORTS, '>>', $sdl2_exports) or die("Can't open $sdl2_exports: $!\n"); opendir(HEADERS, 'include') or die("Can't open include dir: $!\n"); while (my $d = readdir(HEADERS)) { @@ -133,6 +135,7 @@ while (my $d = readdir(HEADERS)) { print("NEW: $decl\n"); print SDL_DYNAPI_PROCS_H "SDL_DYNAPI_PROC($rc,$fn,$paramstr,$argstr,$retstr)\n"; print SDL_DYNAPI_OVERRIDES_H "#define $fn ${fn}_REAL\n"; + print SDL2_EXPORTS "++'_${fn}'.'SDL2.dll'.'${fn}'\n"; } else { print("Failed to parse decl [$decl]!\n"); } @@ -143,5 +146,6 @@ closedir(HEADERS); close(SDL_DYNAPI_PROCS_H); close(SDL_DYNAPI_OVERRIDES_H); +close(SDL2_EXPORTS); # vi: set ts=4 sw=4 expandtab: diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index caa8b87eb..962120dbf 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -150,13 +150,19 @@ SDL_PollSentinelChanged(void *userdata, const char *name, const char *oldValue, SDL_EventState(SDL_POLLSENTINEL, SDL_GetStringBoolean(hint, SDL_TRUE) ? SDL_ENABLE : SDL_DISABLE); } -/* 0 (default) means no logging, 1 means logging, 2 means logging with mouse and finger motion */ -static int SDL_DoEventLogging = 0; +/** + * Verbosity of logged events as defined in SDL_HINT_EVENT_LOGGING: + * - 0: (default) no logging + * - 1: logging of most events + * - 2: as above, plus mouse and finger motion + * - 3: as above, plus SDL_SysWMEvents + */ +static int SDL_EventLoggingVerbosity = 0; static void SDLCALL SDL_EventLoggingChanged(void *userdata, const char *name, const char *oldValue, const char *hint) { - SDL_DoEventLogging = (hint && *hint) ? SDL_clamp(SDL_atoi(hint), 0, 2) : 0; + SDL_EventLoggingVerbosity = (hint && *hint) ? SDL_clamp(SDL_atoi(hint), 0, 3) : 0; } static void @@ -166,7 +172,7 @@ SDL_LogEvent(const SDL_Event *event) char details[128]; /* sensor/mouse/finger motion are spammy, ignore these if they aren't demanded. */ - if ( (SDL_DoEventLogging < 2) && + if ( (SDL_EventLoggingVerbosity < 2) && ( (event->type == SDL_MOUSEMOTION) || (event->type == SDL_FINGERMOTION) || (event->type == SDL_CONTROLLERTOUCHPADMOTION) || @@ -175,6 +181,11 @@ SDL_LogEvent(const SDL_Event *event) return; } + /* window manager events are even more spammy, and don't provide much useful info. */ + if ((SDL_EventLoggingVerbosity < 3) && (event->type == SDL_SYSWMEVENT)) { + return; + } + /* this is to make SDL_snprintf() calls cleaner. */ #define uint unsigned int @@ -590,7 +601,7 @@ SDL_AddEvent(SDL_Event * event) SDL_EventQ.free = entry->next; } - if (SDL_DoEventLogging) { + if (SDL_EventLoggingVerbosity > 0) { SDL_LogEvent(event); } diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c index 14e79ca49..be1b7953e 100644 --- a/src/events/SDL_keyboard.c +++ b/src/events/SDL_keyboard.c @@ -282,6 +282,10 @@ static const SDL_Keycode SDL_default_keymap[SDL_NUM_SCANCODES] = { SDLK_APP2, SDLK_AUDIOREWIND, SDLK_AUDIOFASTFORWARD, + SDLK_SOFTLEFT, + SDLK_SOFTRIGHT, + SDLK_CALL, + SDLK_ENDCALL, }; static const char *SDL_scancode_names[SDL_NUM_SCANCODES] = { @@ -518,6 +522,10 @@ static const char *SDL_scancode_names[SDL_NUM_SCANCODES] = { "App2", "AudioRewind", "AudioFastForward", + "SoftLeft", + "SoftRight", + "Call", + "EndCall", }; /* Taken from SDL_iconv() */ diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index 254182cc5..dfa9a6c42 100644 --- a/src/events/SDL_mouse.c +++ b/src/events/SDL_mouse.c @@ -867,7 +867,7 @@ SDL_GetGlobalMouseState(int *x, int *y) } void -SDL_WarpMouseInWindow(SDL_Window * window, int x, int y) +SDL_PerformWarpMouseInWindow(SDL_Window *window, int x, int y, SDL_bool ignore_relative_mode) { SDL_Mouse *mouse = SDL_GetMouse(); @@ -883,6 +883,20 @@ SDL_WarpMouseInWindow(SDL_Window * window, int x, int y) return; } + if (mouse->relative_mode && !ignore_relative_mode) { + /* 2.0.22 made warping in relative mode actually functional, which + * surprised many applications that weren't expecting the additional + * mouse motion. + * + * So for now, warping in relative mode adjusts the absolution position + * but doesn't generate motion events. + */ + mouse->x = x; + mouse->y = y; + mouse->has_position = SDL_TRUE; + return; + } + /* Ignore the previous position when we warp */ mouse->has_position = SDL_FALSE; @@ -894,6 +908,12 @@ SDL_WarpMouseInWindow(SDL_Window * window, int x, int y) } } +void +SDL_WarpMouseInWindow(SDL_Window * window, int x, int y) +{ + SDL_PerformWarpMouseInWindow(window, x, y, SDL_FALSE); +} + int SDL_WarpMouseGlobal(int x, int y) { @@ -953,8 +973,9 @@ SDL_SetRelativeMouseMode(SDL_bool enabled) if (enabled && focusWindow) { SDL_SetMouseFocus(focusWindow); - if (mouse->relative_mode_warp) - SDL_WarpMouseInWindow(focusWindow, focusWindow->w/2, focusWindow->h/2); + if (mouse->relative_mode_warp) { + SDL_PerformWarpMouseInWindow(focusWindow, focusWindow->w/2, focusWindow->h/2, SDL_TRUE); + } } if (focusWindow) { @@ -962,7 +983,7 @@ SDL_SetRelativeMouseMode(SDL_bool enabled) /* Put the cursor back to where the application expects it */ if (!enabled) { - SDL_WarpMouseInWindow(focusWindow, mouse->x, mouse->y); + SDL_PerformWarpMouseInWindow(focusWindow, mouse->x, mouse->y, SDL_TRUE); } SDL_UpdateMouseCapture(SDL_FALSE); @@ -998,7 +1019,8 @@ SDL_UpdateMouseCapture(SDL_bool force_release) } if (!force_release) { - if (mouse->capture_desired || (mouse->auto_capture && SDL_GetMouseState(NULL, NULL) != 0)) { + if (SDL_GetMessageBoxCount() == 0 && + (mouse->capture_desired || (mouse->auto_capture && SDL_GetMouseState(NULL, NULL) != 0))) { if (!mouse->relative_mode) { capture_window = SDL_GetKeyboardFocus(); } @@ -1006,21 +1028,34 @@ SDL_UpdateMouseCapture(SDL_bool force_release) } 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; + /* We can get here recursively on Windows, so make sure we complete + * all of the window state operations before we change the capture state + * (e.g. https://github.com/libsdl-org/SDL/pull/5608) + */ + SDL_Window *previous_capture = mouse->capture_window; + + if (previous_capture) { + previous_capture->flags &= ~SDL_WINDOW_MOUSE_CAPTURE; } if (capture_window) { - if (mouse->CaptureMouse(capture_window) < 0) { - /* CaptureMouse() will have set an error */ - return -1; - } capture_window->flags |= SDL_WINDOW_MOUSE_CAPTURE; } mouse->capture_window = capture_window; + + if (mouse->CaptureMouse(capture_window) < 0) { + /* CaptureMouse() will have set an error, just restore the state */ + if (previous_capture) { + previous_capture->flags |= SDL_WINDOW_MOUSE_CAPTURE; + } + if (capture_window) { + capture_window->flags &= ~SDL_WINDOW_MOUSE_CAPTURE; + } + mouse->capture_window = previous_capture; + + return -1; + } } return 0; } @@ -1034,6 +1069,17 @@ SDL_CaptureMouse(SDL_bool enabled) return SDL_Unsupported(); } +#ifdef __WIN32__ + /* Windows mouse capture is tied to the current thread, and must be called + * from the thread that created the window being captured. Since we update + * the mouse capture state from the event processing, any application state + * changes must be processed on that thread as well. + */ + if (!SDL_OnVideoThread()) { + return SDL_SetError("SDL_CaptureMouse() must be called on the main thread"); + } +#endif /* __WIN32__ */ + if (enabled && SDL_GetKeyboardFocus() == NULL) { return SDL_SetError("No window has focus"); } diff --git a/src/events/SDL_mouse_c.h b/src/events/SDL_mouse_c.h index f06934b6f..70c320851 100644 --- a/src/events/SDL_mouse_c.h +++ b/src/events/SDL_mouse_c.h @@ -152,6 +152,9 @@ extern int SDL_SendMouseButtonClicks(SDL_Window * window, SDL_MouseID mouseID, U /* Send a mouse wheel event */ extern int SDL_SendMouseWheel(SDL_Window * window, SDL_MouseID mouseID, float x, float y, SDL_MouseWheelDirection direction); +/* Warp the mouse within the window, potentially overriding relative mode */ +extern void SDL_PerformWarpMouseInWindow(SDL_Window *window, int x, int y, SDL_bool ignore_relative_mode); + /* Shutdown the mouse subsystem */ extern void SDL_MouseQuit(void); diff --git a/src/events/scancodes_darwin.h b/src/events/scancodes_darwin.h index a511e11c8..75564112a 100644 --- a/src/events/scancodes_darwin.h +++ b/src/events/scancodes_darwin.h @@ -25,7 +25,7 @@ - Apple USB keyboard driver source - experimentation on various ADB and USB ISO keyboards and one ADB ANSI keyboard */ -/* *INDENT-OFF* */ +/* *INDENT-OFF* */ /* clang-format off */ static const SDL_Scancode darwin_scancode_table[] = { /* 0 */ SDL_SCANCODE_A, /* 1 */ SDL_SCANCODE_S, @@ -156,4 +156,4 @@ static const SDL_Scancode darwin_scancode_table[] = { /* 126 */ SDL_SCANCODE_UP, /* 127 */ SDL_SCANCODE_POWER }; -/* *INDENT-ON* */ +/* *INDENT-ON* */ /* clang-format on */ diff --git a/src/events/scancodes_linux.h b/src/events/scancodes_linux.h index 72637b239..f274e993a 100644 --- a/src/events/scancodes_linux.h +++ b/src/events/scancodes_linux.h @@ -24,7 +24,7 @@ Sources: - Linux kernel source input.h */ -/* *INDENT-OFF* */ +/* *INDENT-OFF* */ /* clang-format off */ static SDL_Scancode const linux_scancode_table[] = { /* 0 */ SDL_SCANCODE_UNKNOWN, /* 1 */ SDL_SCANCODE_ESCAPE, @@ -260,4 +260,4 @@ static SDL_Scancode const linux_scancode_table[] = { /* 235 */ SDL_SCANCODE_UNKNOWN, /* KEY_DOCUMENTS */ /* 236 */ SDL_SCANCODE_UNKNOWN, /* KEY_BATTERY */ }; -/* *INDENT-ON* */ +/* *INDENT-ON* */ /* clang-format on */ diff --git a/src/events/scancodes_windows.h b/src/events/scancodes_windows.h index eec768d62..9fc7067a2 100644 --- a/src/events/scancodes_windows.h +++ b/src/events/scancodes_windows.h @@ -23,7 +23,7 @@ /* Windows scancode to SDL scancode mapping table */ /* derived from Microsoft scan code document, http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc */ -/* *INDENT-OFF* */ +/* *INDENT-OFF* */ /* clang-format off */ static const SDL_Scancode windows_scancode_table[] = { /* 0 1 2 3 4 5 6 7 */ @@ -52,4 +52,4 @@ static const SDL_Scancode windows_scancode_table[] = SDL_SCANCODE_INTERNATIONAL2, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL1, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, /* 7 */ SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL4, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL5, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL3, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN /* 7 */ }; -/* *INDENT-ON* */ +/* *INDENT-ON* */ /* clang-format on */ diff --git a/src/events/scancodes_xfree86.h b/src/events/scancodes_xfree86.h index 7046b7a8f..1ce2a8c57 100644 --- a/src/events/scancodes_xfree86.h +++ b/src/events/scancodes_xfree86.h @@ -28,7 +28,7 @@ Sources: - atKeyNames.h from XFree86 source code */ -/* *INDENT-OFF* */ +/* *INDENT-OFF* */ /* clang-format off */ static const SDL_Scancode xfree86_scancode_table[] = { /* 0 */ SDL_SCANCODE_UNKNOWN, /* 1 */ SDL_SCANCODE_ESCAPE, @@ -509,4 +509,4 @@ static const SDL_Scancode xvnc_scancode_table[] = { #endif /* scancodes_xfree86_h_ */ -/* *INDENT-ON* */ +/* *INDENT-ON* */ /* clang-format on */ diff --git a/src/file/SDL_rwops.c b/src/file/SDL_rwops.c index 670d4dd9a..0b4cc17b2 100644 --- a/src/file/SDL_rwops.c +++ b/src/file/SDL_rwops.c @@ -62,235 +62,6 @@ #include "nacl_io/nacl_io.h" #endif -#ifdef __VITA__ - -#include -#include - -#define READAHEAD_BUFFER_SIZE 1024 -static int SDLCALL -vita_file_open(SDL_RWops * context, const char *filename, const char *mode) -{ - int h; - int open_flags; - SDL_bool has_r; - SDL_bool has_w; - SDL_bool has_a; - SDL_bool has_plus; - - if (!context) - return -1; /* failed (invalid call) */ - - context->hidden.vitaio.h = -1; /* mark this as unusable */ - context->hidden.vitaio.buffer.data = NULL; - context->hidden.vitaio.buffer.size = 0; - context->hidden.vitaio.buffer.left = 0; - - open_flags = 0; - - /* "r" = reading, file must exist */ - /* "w" = writing, truncate existing, file may not exist */ - /* "r+"= reading or writing, file must exist */ - /* "a" = writing, append file may not exist */ - /* "a+"= append + read, file may not exist */ - /* "w+" = read, write, truncate. file may not exist */ - - has_r = SDL_strchr(mode, 'r') != NULL; - has_w = SDL_strchr(mode, 'w') != NULL; - has_a = SDL_strchr(mode, 'a') != NULL; - has_plus = SDL_strchr(mode, '+') != NULL; - - if (has_plus) - { - if (has_r || has_w || has_a) - { - open_flags |= SCE_O_RDWR; - } - } - else - { - if (has_r) - { - open_flags |= SCE_O_RDONLY; - } - if (has_w || has_a) - { - open_flags |= SCE_O_WRONLY; - } - } - if (has_w || has_a) - { - open_flags |= SCE_O_CREAT; - } - if (has_w) - { - open_flags |= SCE_O_TRUNC; - } - if (has_a) - { - open_flags |= SCE_O_APPEND; - } - - context->hidden.vitaio.buffer.data = - (char *) SDL_malloc(READAHEAD_BUFFER_SIZE); - if (!context->hidden.vitaio.buffer.data) { - return SDL_OutOfMemory(); - } - - /* Try to open the file on the filesystem first */ - h = sceIoOpen(filename, open_flags, 0777); - - if (h < 0) { - /* Try opening it from app0:/ container if it's a relative path */ - char path[4096]; - SDL_snprintf(path, 4096, "app0:/%s", filename); - h = sceIoOpen(path, open_flags, 0777); - } - - if (h < 0) { - SDL_free(context->hidden.vitaio.buffer.data); - context->hidden.vitaio.buffer.data = NULL; - SDL_SetError("Couldn't open %s", filename); - return -2; /* failed (sceIoOpen) */ - } - context->hidden.vitaio.h = h; - - return 0; /* ok */ -} - -static Sint64 SDLCALL -vita_file_size(SDL_RWops * context) -{ - SceIoStat st; - if (!context || context->hidden.vitaio.h < 0) { - return SDL_SetError("vita_file_size: invalid context/file not opened"); - } - - if (sceIoGetstatByFd(context->hidden.vitaio.h, &st) < 0) { - return SDL_SetError("vita_file_size: could not get file size"); - } - return st.st_size; -} - -static Sint64 SDLCALL -vita_file_seek(SDL_RWops * context, Sint64 offset, int whence) -{ - int vitawhence; - - if (!context || context->hidden.vitaio.h < 0) { - return SDL_SetError("vita_file_seek: invalid context/file not opened"); - } - - /* FIXME: We may be able to satisfy the seek within buffered data */ - if (whence == RW_SEEK_CUR && context->hidden.vitaio.buffer.left) { - offset -= (long)context->hidden.vitaio.buffer.left; - } - context->hidden.vitaio.buffer.left = 0; - - switch (whence) { - case RW_SEEK_SET: - vitawhence = SCE_SEEK_SET; - break; - case RW_SEEK_CUR: - vitawhence = SCE_SEEK_CUR; - break; - case RW_SEEK_END: - vitawhence = SCE_SEEK_END; - break; - default: - return SDL_SetError("vita_file_seek: Unknown value for 'whence'"); - } - - return sceIoLseek(context->hidden.vitaio.h, offset, vitawhence); -} - -static size_t SDLCALL -vita_file_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum) -{ - size_t total_need; - size_t total_read = 0; - size_t read_ahead; - size_t byte_read; - - total_need = size * maxnum; - - if (!context || context->hidden.vitaio.h < 0 || !total_need) { - return 0; - } - - if (context->hidden.vitaio.buffer.left > 0) { - void *data = (char *) context->hidden.vitaio.buffer.data + - context->hidden.vitaio.buffer.size - - context->hidden.vitaio.buffer.left; - read_ahead = - SDL_min(total_need, context->hidden.vitaio.buffer.left); - SDL_memcpy(ptr, data, read_ahead); - context->hidden.vitaio.buffer.left -= read_ahead; - - if (read_ahead == total_need) { - return maxnum; - } - ptr = (char *) ptr + read_ahead; - total_need -= read_ahead; - total_read += read_ahead; - } - - if (total_need < READAHEAD_BUFFER_SIZE) { - byte_read = sceIoRead(context->hidden.vitaio.h, context->hidden.vitaio.buffer.data, READAHEAD_BUFFER_SIZE); - read_ahead = SDL_min(total_need, (int) byte_read); - SDL_memcpy(ptr, context->hidden.vitaio.buffer.data, read_ahead); - context->hidden.vitaio.buffer.size = byte_read; - context->hidden.vitaio.buffer.left = byte_read - read_ahead; - total_read += read_ahead; - } else { - byte_read = sceIoRead(context->hidden.vitaio.h, ptr, total_need); - total_read += byte_read; - } - return (total_read / size); -} - -static size_t SDLCALL -vita_file_write(SDL_RWops * context, const void *ptr, size_t size, - size_t num) -{ - - size_t total_bytes; - size_t byte_written; - size_t nwritten; - - total_bytes = size * num; - - if (!context || context->hidden.vitaio.h < 0 || !size || !total_bytes) { - return 0; - } - - if (context->hidden.vitaio.buffer.left) { - sceIoLseek(context->hidden.vitaio.h, -(SceOff)context->hidden.vitaio.buffer.left, SCE_SEEK_CUR); - context->hidden.vitaio.buffer.left = 0; - } - - byte_written = sceIoWrite(context->hidden.vitaio.h, ptr, total_bytes); - - nwritten = byte_written / size; - return nwritten; -} - -static int SDLCALL -vita_file_close(SDL_RWops * context) -{ - if (context) { - if (context->hidden.vitaio.h >= 0) { - sceIoClose(context->hidden.vitaio.h); - context->hidden.vitaio.h = -1; /* to be sure */ - } - SDL_free(context->hidden.vitaio.buffer.data); - context->hidden.vitaio.buffer.data = NULL; - SDL_FreeRW(context); - } - return 0; -} -#endif - #ifdef __WIN32__ /* Functions to read/write Win32 API file pointers */ @@ -817,20 +588,6 @@ SDL_RWFromFile(const char *file, const char *mode) rwops->write = windows_file_write; rwops->close = windows_file_close; rwops->type = SDL_RWOPS_WINFILE; -#elif defined(__VITA__) - rwops = SDL_AllocRW(); - if (!rwops) - return NULL; /* SDL_SetError already setup by SDL_AllocRW() */ - if (vita_file_open(rwops, file, mode) < 0) { - SDL_FreeRW(rwops); - return NULL; - } - rwops->size = vita_file_size; - rwops->seek = vita_file_seek; - rwops->read = vita_file_read; - rwops->write = vita_file_write; - rwops->close = vita_file_close; - rwops->type = SDL_RWOPS_VITAFILE; #elif HAVE_STDIO_H { #if __APPLE__ && !SDL_FILE_DISABLED // TODO: add dummy? diff --git a/src/filesystem/psp/SDL_sysfilesystem.c b/src/filesystem/psp/SDL_sysfilesystem.c index e9c6ee49e..4abb90ad7 100644 --- a/src/filesystem/psp/SDL_sysfilesystem.c +++ b/src/filesystem/psp/SDL_sysfilesystem.c @@ -34,44 +34,44 @@ char * SDL_GetBasePath(void) { - char *retval = NULL; - size_t len; - char cwd[FILENAME_MAX]; - - getcwd(cwd, sizeof(cwd)); - len = SDL_strlen(cwd) + 2; - retval = (char *) SDL_malloc(len); - SDL_snprintf(retval, len, "%s/", cwd); + char *retval = NULL; + size_t len; + char cwd[FILENAME_MAX]; - return retval; + getcwd(cwd, sizeof(cwd)); + len = SDL_strlen(cwd) + 2; + retval = (char *) SDL_malloc(len); + SDL_snprintf(retval, len, "%s/", cwd); + + return retval; } char * SDL_GetPrefPath(const char *org, const char *app) { - char *retval = NULL; - size_t len; - char *base = SDL_GetBasePath(); - if (!app) { - SDL_InvalidParamError("app"); - return NULL; - } - if(!org) { - org = ""; - } + char *retval = NULL; + size_t len; + char *base = SDL_GetBasePath(); + if (!app) { + SDL_InvalidParamError("app"); + return NULL; + } + if(!org) { + org = ""; + } - len = SDL_strlen(base) + SDL_strlen(org) + SDL_strlen(app) + 4; - retval = (char *) SDL_malloc(len); + len = SDL_strlen(base) + SDL_strlen(org) + SDL_strlen(app) + 4; + retval = (char *) SDL_malloc(len); - if (*org) { - SDL_snprintf(retval, len, "%s%s/%s/", base, org, app); - } else { - SDL_snprintf(retval, len, "%s%s/", base, app); - } - free(base); + if (*org) { + SDL_snprintf(retval, len, "%s%s/%s/", base, org, app); + } else { + SDL_snprintf(retval, len, "%s%s/", base, app); + } + free(base); - mkdir(retval, 0755); - return retval; + mkdir(retval, 0755); + return retval; } #endif /* SDL_FILESYSTEM_PSP */ diff --git a/src/hidapi/windows/hid.c b/src/hidapi/windows/hid.c index f0a30c7d1..8dfd11d05 100644 --- a/src/hidapi/windows/hid.c +++ b/src/hidapi/windows/hid.c @@ -43,21 +43,6 @@ typedef LONG NTSTATUS; #endif -/* SDL C runtime functions */ -#include "SDL_stdinc.h" - -#define calloc SDL_calloc -#define free SDL_free -#define malloc SDL_malloc -#define memcpy SDL_memcpy -#define memset SDL_memset -#define strcmp SDL_strcmp -#define strlen SDL_strlen -#define strstr SDL_strstr -#define strtol SDL_strtol -#define wcscmp SDL_wcscmp -#define _wcsdup SDL_wcsdup - /* The maximum number of characters that can be passed into the HidD_Get*String() functions without it failing.*/ #define MAX_STRING_WCHARS 0xFFF @@ -94,11 +79,26 @@ extern "C" { } /* extern "C" */ #endif +#include "../hidapi/hidapi.h" + /*#include */ /*#include */ +/* SDL C runtime functions */ +#include "SDL_stdinc.h" + +#define calloc SDL_calloc +#define free SDL_free +#define malloc SDL_malloc +#define memcpy SDL_memcpy +#define memset SDL_memset +#define strcmp SDL_strcmp +#define strlen SDL_strlen +#define strstr SDL_strstr +#define strtol SDL_strtol +#define wcscmp SDL_wcscmp +#define _wcsdup SDL_wcsdup -#include "../hidapi/hidapi.h" #undef MIN #define MIN(x,y) ((x) < (y)? (x): (y)) diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c index e27922a6d..4e573f55b 100644 --- a/src/joystick/SDL_gamecontroller.c +++ b/src/joystick/SDL_gamecontroller.c @@ -696,19 +696,20 @@ static ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickG return s_pXInputMapping; } #endif + if (!mapping) { + if (SDL_IsJoystickHIDAPI(guid)) { + mapping = SDL_CreateMappingForHIDAPIController(guid); + } else if (SDL_IsJoystickRAWINPUT(guid)) { + mapping = SDL_CreateMappingForRAWINPUTController(guid); + } else if (SDL_IsJoystickWGI(guid)) { + mapping = SDL_CreateMappingForWGIController(guid); + } else if (SDL_IsJoystickVirtual(guid)) { + /* We'll pick up a robust mapping in VIRTUAL_JoystickGetGamepadMapping */ #ifdef __ANDROID__ - if (!mapping && !SDL_IsJoystickHIDAPI(guid)) { - mapping = SDL_CreateMappingForAndroidController(guid); - } + } else { + mapping = SDL_CreateMappingForAndroidController(guid); #endif - if (!mapping && SDL_IsJoystickHIDAPI(guid)) { - mapping = SDL_CreateMappingForHIDAPIController(guid); - } - if (!mapping && SDL_IsJoystickRAWINPUT(guid)) { - mapping = SDL_CreateMappingForRAWINPUTController(guid); - } - if (!mapping && SDL_IsJoystickWGI(guid)) { - mapping = SDL_CreateMappingForWGIController(guid); + } } } return mapping; @@ -1258,6 +1259,11 @@ static ControllerMapping_t *SDL_PrivateGenerateAutomaticControllerMapping(const SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "dpdown", &raw_map->dpdown); SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "dpleft", &raw_map->dpleft); SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "dpright", &raw_map->dpright); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "misc1", &raw_map->misc1); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "paddle1", &raw_map->paddle1); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "paddle2", &raw_map->paddle2); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "paddle3", &raw_map->paddle3); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "paddle4", &raw_map->paddle4); SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "leftx", &raw_map->leftx); SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "lefty", &raw_map->lefty); SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "rightx", &raw_map->rightx); @@ -1732,6 +1738,20 @@ SDL_GameControllerNameForIndex(int device_index) } +/* + * Get the implementation dependent path of a controller + */ +const char * +SDL_GameControllerPathForIndex(int device_index) +{ + ControllerMapping_t *pSupportedController = SDL_PrivateGetControllerMapping(device_index); + if (pSupportedController) { + return SDL_JoystickPathForIndex(device_index); + } + return NULL; +} + + /** * Get the type of a game controller. */ @@ -2294,6 +2314,15 @@ SDL_GameControllerName(SDL_GameController *gamecontroller) } } +const char * +SDL_GameControllerPath(SDL_GameController *gamecontroller) +{ + if (!gamecontroller) + return NULL; + + return SDL_JoystickPath(SDL_GameControllerGetJoystick(gamecontroller)); +} + SDL_GameControllerType SDL_GameControllerGetType(SDL_GameController *gamecontroller) { diff --git a/src/joystick/SDL_gamecontrollerdb.h b/src/joystick/SDL_gamecontrollerdb.h index 61c388fb1..5832f3239 100644 --- a/src/joystick/SDL_gamecontrollerdb.h +++ b/src/joystick/SDL_gamecontrollerdb.h @@ -748,8 +748,11 @@ static const char *s_ControllerMappings [] = "030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,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,", "030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,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,", "03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", + "03000000de2800000112000011010000,Steam Controller,a:b2,b:b3,x:b4,y:b5,back:b10,guide:b12,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:-a5,dpdown:+a5,dpleft:-a4,dpright:+a4,paddle1:b15,paddle2:b16,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a7,righttrigger:a6,", "03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", + "03000000de2800000211000011010000,Steam Controller,a:b2,b:b3,x:b4,y:b5,back:b10,guide:b12,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:-a5,dpdown:+a5,dpleft:-a4,dpright:+a4,paddle1:b15,paddle2:b16,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a7,righttrigger:a6,", "03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", + "03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,x:b4,y:b5,back:b10,guide:b12,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:-a5,dpdown:+a5,dpleft:-a4,dpright:+a4,paddle1:b15,paddle2:b16,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a7,righttrigger:a6,", "03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,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,", "05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", "05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", @@ -896,9 +899,6 @@ static const char *s_ControllerMappings [] = "050000005e040000e0020000df070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", "050000005e040000e0020000ff070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,", #endif -#if defined(SDL_JOYSTICK_VIRTUAL) - "00000000000000000000000000007601,Virtual Joystick,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", -#endif #if defined(SDL_JOYSTICK_EMSCRIPTEN) "default,Standard Gamepad,a:b0,b:b1,back:b8,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b16,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", #endif diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 21268a4d5..a51ac517a 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -323,6 +323,28 @@ SDL_JoystickNameForIndex(int device_index) return name; } +/* + * Get the implementation dependent path of a joystick + */ +const char * +SDL_JoystickPathForIndex(int device_index) +{ + SDL_JoystickDriver *driver; + const char *path = NULL; + + SDL_LockJoysticks(); + if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) { + path = driver->GetDevicePath(device_index); + } + SDL_UnlockJoysticks(); + + /* FIXME: Really we should reference count this path so it doesn't go away after unlock */ + if (!path) { + SDL_Unsupported(); + } + return path; +} + /* * Get the player index of a joystick, or -1 if it's not available */ @@ -389,6 +411,8 @@ SDL_JoystickOpen(int device_index) SDL_Joystick *joystick; SDL_Joystick *joysticklist; const char *joystickname = NULL; + const char *joystickpath = NULL; + SDL_JoystickPowerLevel initial_power_level; SDL_LockJoysticks(); @@ -438,6 +462,13 @@ SDL_JoystickOpen(int device_index) joystick->name = NULL; } + joystickpath = driver->GetDevicePath(device_index); + if (joystickpath) { + joystick->path = SDL_strdup(joystickpath); + } else { + joystick->path = NULL; + } + joystick->guid = driver->GetDeviceGUID(device_index); if (joystick->naxes > 0) { @@ -481,6 +512,11 @@ SDL_JoystickOpen(int device_index) SDL_UnlockJoysticks(); + /* send initial battery event */ + initial_power_level = joystick->epowerlevel; + joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN; + SDL_PrivateJoystickBatteryLevel(joystick, initial_power_level); + driver->Update(joystick); return joystick; @@ -489,9 +525,23 @@ SDL_JoystickOpen(int device_index) int SDL_JoystickAttachVirtual(SDL_JoystickType type, int naxes, int nbuttons, int nhats) +{ + SDL_VirtualJoystickDesc desc; + + SDL_zero(desc); + desc.version = SDL_VIRTUAL_JOYSTICK_DESC_VERSION; + desc.type = (Uint16)type; + desc.naxes = (Uint16)naxes; + desc.nbuttons = (Uint16)nbuttons; + desc.nhats = (Uint16)nhats; + return SDL_JoystickAttachVirtualEx(&desc); +} + +int +SDL_JoystickAttachVirtualEx(const SDL_VirtualJoystickDesc *desc) { #if SDL_JOYSTICK_VIRTUAL - return SDL_JoystickAttachVirtualInner(type, naxes, nbuttons, nhats); + return SDL_JoystickAttachVirtualInner(desc); #else return SDL_SetError("SDL not built with virtual-joystick support"); #endif @@ -837,6 +887,23 @@ SDL_JoystickName(SDL_Joystick *joystick) return joystick->name; } +/* + * Get the implementation dependent path of this joystick + */ +const char * +SDL_JoystickPath(SDL_Joystick *joystick) +{ + if (!SDL_PrivateJoystickValid(joystick)) { + return NULL; + } + + if (!joystick->path) { + SDL_Unsupported(); + return NULL; + } + return joystick->path; +} + /** * Get the player index of an opened joystick, or -1 if it's not available */ @@ -1009,14 +1076,13 @@ SDL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) SDL_LockJoysticks(); isfreshvalue = red != joystick->led_red || - green != joystick->led_green || - blue != joystick->led_blue; + green != joystick->led_green || + blue != joystick->led_blue; - if ( isfreshvalue || SDL_TICKS_PASSED( SDL_GetTicks(), joystick->led_expiration ) ) { + if (isfreshvalue || SDL_TICKS_PASSED(SDL_GetTicks(), joystick->led_expiration)) { result = joystick->driver->SetLED(joystick, red, green, blue); joystick->led_expiration = SDL_GetTicks() + SDL_LED_MIN_REPEAT_MS; - } - else { + } else { /* Avoid spamming the driver */ result = 0; } @@ -1103,6 +1169,7 @@ SDL_JoystickClose(SDL_Joystick *joystick) } SDL_free(joystick->name); + SDL_free(joystick->path); SDL_free(joystick->serial); /* Free the data associated with this joystick */ @@ -2724,7 +2791,19 @@ SDL_JoystickGUID SDL_JoystickGetGUIDFromString(const char *pchGUID) /* update the power level for this joystick */ void SDL_PrivateJoystickBatteryLevel(SDL_Joystick *joystick, SDL_JoystickPowerLevel ePowerLevel) { - joystick->epowerlevel = ePowerLevel; + SDL_assert(joystick->ref_count); /* make sure we are calling this only for update, not for initialisation */ + if (ePowerLevel != joystick->epowerlevel) { +#if !SDL_EVENTS_DISABLED + if (SDL_GetEventState(SDL_JOYBATTERYUPDATED) == SDL_ENABLE) { + SDL_Event event; + event.type = SDL_JOYBATTERYUPDATED; + event.jbattery.which = joystick->instance_id; + event.jbattery.level = ePowerLevel; + SDL_PushEvent(&event); + } +#endif /* !SDL_EVENTS_DISABLED */ + joystick->epowerlevel = ePowerLevel; + } } /* return its power level */ diff --git a/src/joystick/SDL_joystick_c.h b/src/joystick/SDL_joystick_c.h index 312e11337..a7aa6b714 100644 --- a/src/joystick/SDL_joystick_c.h +++ b/src/joystick/SDL_joystick_c.h @@ -168,6 +168,11 @@ typedef struct _SDL_GamepadMapping SDL_InputMapping dpdown; SDL_InputMapping dpleft; SDL_InputMapping dpright; + SDL_InputMapping misc1; + SDL_InputMapping paddle1; + SDL_InputMapping paddle2; + SDL_InputMapping paddle3; + SDL_InputMapping paddle4; SDL_InputMapping leftx; SDL_InputMapping lefty; SDL_InputMapping rightx; diff --git a/src/joystick/SDL_sysjoystick.h b/src/joystick/SDL_sysjoystick.h index 32726be5a..0d3767fd8 100644 --- a/src/joystick/SDL_sysjoystick.h +++ b/src/joystick/SDL_sysjoystick.h @@ -65,6 +65,7 @@ struct _SDL_Joystick { SDL_JoystickID instance_id; /* Device instance, monotonically increasing from 0 */ char *name; /* Joystick name - system dependent */ + char *path; /* Joystick path - system dependent */ char *serial; /* Joystick serial */ SDL_JoystickGUID guid; /* Joystick guid */ @@ -118,6 +119,7 @@ struct _SDL_Joystick }; /* Device bus definitions */ +#define SDL_HARDWARE_BUS_VIRTUAL 0x00 #define SDL_HARDWARE_BUS_USB 0x03 #define SDL_HARDWARE_BUS_BLUETOOTH 0x05 @@ -146,6 +148,9 @@ typedef struct _SDL_JoystickDriver /* Function to get the device-dependent name of a joystick */ const char *(*GetDeviceName)(int device_index); + /* Function to get the device-dependent path of a joystick */ + const char *(*GetDevicePath)(int device_index); + /* Function to get the player index of a joystick */ int (*GetDevicePlayerIndex)(int device_index); diff --git a/src/joystick/android/SDL_sysjoystick.c b/src/joystick/android/SDL_sysjoystick.c index aef014d16..104724afd 100644 --- a/src/joystick/android/SDL_sysjoystick.c +++ b/src/joystick/android/SDL_sysjoystick.c @@ -558,6 +558,12 @@ ANDROID_JoystickGetDeviceName(int device_index) return JoystickByDevIndex(device_index)->name; } +static const char * +ANDROID_JoystickGetDevicePath(int device_index) +{ + return NULL; +} + static int ANDROID_JoystickGetDevicePlayerIndex(int device_index) { @@ -713,6 +719,7 @@ SDL_JoystickDriver SDL_ANDROID_JoystickDriver = ANDROID_JoystickGetCount, ANDROID_JoystickDetect, ANDROID_JoystickGetDeviceName, + ANDROID_JoystickGetDevicePath, ANDROID_JoystickGetDevicePlayerIndex, ANDROID_JoystickSetDevicePlayerIndex, ANDROID_JoystickGetDeviceGUID, diff --git a/src/joystick/bsd/SDL_bsdjoystick.c b/src/joystick/bsd/SDL_bsdjoystick.c index f8859a534..d7b4d4730 100644 --- a/src/joystick/bsd/SDL_bsdjoystick.c +++ b/src/joystick/bsd/SDL_bsdjoystick.c @@ -268,9 +268,15 @@ static const char * BSD_JoystickGetDeviceName(int device_index) { if (joydevnames[device_index] != NULL) { - return (joydevnames[device_index]); + return joydevnames[device_index]; } - return (joynames[device_index]); + return joynames[device_index]; +} + +static const char * +BSD_JoystickGetDevicePath(int device_index) +{ + return joynames[device_index]; } static int @@ -807,6 +813,7 @@ SDL_JoystickDriver SDL_BSD_JoystickDriver = BSD_JoystickGetCount, BSD_JoystickDetect, BSD_JoystickGetDeviceName, + BSD_JoystickGetDevicePath, BSD_JoystickGetDevicePlayerIndex, BSD_JoystickSetDevicePlayerIndex, BSD_JoystickGetDeviceGUID, diff --git a/src/joystick/darwin/SDL_iokitjoystick.c b/src/joystick/darwin/SDL_iokitjoystick.c index 7f2514728..91072c52e 100644 --- a/src/joystick/darwin/SDL_iokitjoystick.c +++ b/src/joystick/darwin/SDL_iokitjoystick.c @@ -744,7 +744,6 @@ DARWIN_JoystickDetect(void) } } -/* Function to get the device-dependent name of a joystick */ const char * DARWIN_JoystickGetDeviceName(int device_index) { @@ -752,6 +751,12 @@ DARWIN_JoystickGetDeviceName(int device_index) return device ? device->product : "UNKNOWN"; } +const char * +DARWIN_JoystickGetDevicePath(int device_index) +{ + return NULL; +} + static int DARWIN_JoystickGetDevicePlayerIndex(int device_index) { @@ -1115,6 +1120,7 @@ SDL_JoystickDriver SDL_DARWIN_JoystickDriver = DARWIN_JoystickGetCount, DARWIN_JoystickDetect, DARWIN_JoystickGetDeviceName, + DARWIN_JoystickGetDevicePath, DARWIN_JoystickGetDevicePlayerIndex, DARWIN_JoystickSetDevicePlayerIndex, DARWIN_JoystickGetDeviceGUID, diff --git a/src/joystick/dummy/SDL_sysjoystick.c b/src/joystick/dummy/SDL_sysjoystick.c index ec1c8e651..3cf8da5f9 100644 --- a/src/joystick/dummy/SDL_sysjoystick.c +++ b/src/joystick/dummy/SDL_sysjoystick.c @@ -52,6 +52,12 @@ DUMMY_JoystickGetDeviceName(int device_index) return NULL; } +static const char * +DUMMY_JoystickGetDevicePath(int device_index) +{ + return NULL; +} + static int DUMMY_JoystickGetDevicePlayerIndex(int device_index) { @@ -146,6 +152,7 @@ SDL_JoystickDriver SDL_DUMMY_JoystickDriver = DUMMY_JoystickGetCount, DUMMY_JoystickDetect, DUMMY_JoystickGetDeviceName, + DUMMY_JoystickGetDevicePath, DUMMY_JoystickGetDevicePlayerIndex, DUMMY_JoystickSetDevicePlayerIndex, DUMMY_JoystickGetDeviceGUID, diff --git a/src/joystick/emscripten/SDL_sysjoystick.c b/src/joystick/emscripten/SDL_sysjoystick.c index eb0ff2a74..1664a907c 100644 --- a/src/joystick/emscripten/SDL_sysjoystick.c +++ b/src/joystick/emscripten/SDL_sysjoystick.c @@ -280,6 +280,12 @@ EMSCRIPTEN_JoystickGetDeviceName(int device_index) return JoystickByDeviceIndex(device_index)->name; } +static const char * +EMSCRIPTEN_JoystickGetDevicePath(int device_index) +{ + return NULL; +} + static int EMSCRIPTEN_JoystickGetDevicePlayerIndex(int device_index) { @@ -444,6 +450,7 @@ SDL_JoystickDriver SDL_EMSCRIPTEN_JoystickDriver = EMSCRIPTEN_JoystickGetCount, EMSCRIPTEN_JoystickDetect, EMSCRIPTEN_JoystickGetDeviceName, + EMSCRIPTEN_JoystickGetDevicePath, EMSCRIPTEN_JoystickGetDevicePlayerIndex, EMSCRIPTEN_JoystickSetDevicePlayerIndex, EMSCRIPTEN_JoystickGetDeviceGUID, diff --git a/src/joystick/haiku/SDL_haikujoystick.cc b/src/joystick/haiku/SDL_haikujoystick.cc index 38a975227..c0c6e012c 100644 --- a/src/joystick/haiku/SDL_haikujoystick.cc +++ b/src/joystick/haiku/SDL_haikujoystick.cc @@ -64,15 +64,15 @@ extern "C" char name[B_OS_NAME_LENGTH]; /* Search for attached joysticks */ - nports = joystick.CountDevices(); - numjoysticks = 0; - SDL_memset(SDL_joyport, 0, (sizeof SDL_joyport)); - SDL_memset(SDL_joyname, 0, (sizeof SDL_joyname)); + nports = joystick.CountDevices(); + numjoysticks = 0; + SDL_memset(SDL_joyport, 0, (sizeof SDL_joyport)); + SDL_memset(SDL_joyname, 0, (sizeof SDL_joyname)); for (i = 0; (numjoysticks < MAX_JOYSTICKS) && (i < nports); ++i) { if (joystick.GetDeviceName(i, name) == B_OK) { if (joystick.Open(name) != B_ERROR) { - BString stick_name; + BString stick_name; joystick.GetControllerName(&stick_name); SDL_joyport[numjoysticks] = SDL_strdup(name); SDL_joyname[numjoysticks] = SDL_CreateJoystickName(0, 0, NULL, stick_name.String()); @@ -93,12 +93,16 @@ extern "C" { } -/* Function to get the device-dependent name of a joystick */ static const char *HAIKU_JoystickGetDeviceName(int device_index) { return SDL_joyname[device_index]; } + static const char *HAIKU_JoystickGetDevicePath(int device_index) + { + return SDL_joyport[device_index]; + } + static int HAIKU_JoystickGetDevicePlayerIndex(int device_index) { return -1; @@ -298,6 +302,7 @@ extern "C" HAIKU_JoystickGetCount, HAIKU_JoystickDetect, HAIKU_JoystickGetDeviceName, + HAIKU_JoystickGetDevicePath, HAIKU_JoystickGetDevicePlayerIndex, HAIKU_JoystickSetDevicePlayerIndex, HAIKU_JoystickGetDeviceGUID, diff --git a/src/joystick/hidapi/SDL_hidapi_luna.c b/src/joystick/hidapi/SDL_hidapi_luna.c index ead55af34..bf497d224 100644 --- a/src/joystick/hidapi/SDL_hidapi_luna.c +++ b/src/joystick/hidapi/SDL_hidapi_luna.c @@ -267,16 +267,16 @@ HIDAPI_DriverLuna_HandleBluetoothStatePacket(SDL_Joystick *joystick, SDL_DriverL /* Battery level report */ int level = data[1] * 100 / 0xFF; if (level == 0) { - joystick->epowerlevel = SDL_JOYSTICK_POWER_EMPTY; + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY); } else if (level <= 20) { - joystick->epowerlevel = SDL_JOYSTICK_POWER_LOW; + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW); } else if (level <= 70) { - joystick->epowerlevel = SDL_JOYSTICK_POWER_MEDIUM; + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM); } else { - joystick->epowerlevel = SDL_JOYSTICK_POWER_FULL; + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL); } return; diff --git a/src/joystick/hidapi/SDL_hidapi_ps4.c b/src/joystick/hidapi/SDL_hidapi_ps4.c index 8e7699fe4..c11dfb364 100644 --- a/src/joystick/hidapi/SDL_hidapi_ps4.c +++ b/src/joystick/hidapi/SDL_hidapi_ps4.c @@ -801,18 +801,18 @@ HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); if (packet->ucBatteryLevel & 0x10) { - joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED; + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_WIRED); } else { /* Battery level ranges from 0 to 10 */ int level = (packet->ucBatteryLevel & 0xF); if (level == 0) { - joystick->epowerlevel = SDL_JOYSTICK_POWER_EMPTY; + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY); } else if (level <= 2) { - joystick->epowerlevel = SDL_JOYSTICK_POWER_LOW; + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW); } else if (level <= 7) { - joystick->epowerlevel = SDL_JOYSTICK_POWER_MEDIUM; + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM); } else { - joystick->epowerlevel = SDL_JOYSTICK_POWER_FULL; + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL); } } diff --git a/src/joystick/hidapi/SDL_hidapi_rumble.c b/src/joystick/hidapi/SDL_hidapi_rumble.c index bf376277e..9cbdb9599 100644 --- a/src/joystick/hidapi/SDL_hidapi_rumble.c +++ b/src/joystick/hidapi/SDL_hidapi_rumble.c @@ -53,7 +53,7 @@ typedef struct SDL_HIDAPI_RumbleContext static SDL_HIDAPI_RumbleContext rumble_context; -static int SDL_HIDAPI_RumbleThread(void *data) +static int SDLCALL SDL_HIDAPI_RumbleThread(void *data) { SDL_HIDAPI_RumbleContext *ctx = (SDL_HIDAPI_RumbleContext *)data; diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c index 912d613ed..13b5e29d0 100644 --- a/src/joystick/hidapi/SDL_hidapi_switch.c +++ b/src/joystick/hidapi/SDL_hidapi_switch.c @@ -63,6 +63,11 @@ #define SWITCH_GYRO_SCALE 14.2842f #define SWITCH_ACCEL_SCALE 4096.f +#define SWITCH_GYRO_SCALE_OFFSET 13371.0f +#define SWITCH_GYRO_SCALE_MULT 936.0f +#define SWITCH_ACCEL_SCALE_OFFSET 16384.0f +#define SWITCH_ACCEL_SCALE_MULT 4.0f + typedef enum { k_eSwitchInputReportIDs_SubcommandReply = 0x21, k_eSwitchInputReportIDs_FullControllerState = 0x30, @@ -114,6 +119,14 @@ typedef enum { #define k_unSPIStickCalibrationEndOffset 0x604E #define k_unSPIStickCalibrationLength (k_unSPIStickCalibrationEndOffset - k_unSPIStickCalibrationStartOffset + 1) +#define k_unSPIIMUScaleStartOffset 0x6020 +#define k_unSPIIMUScaleEndOffset 0x6037 +#define k_unSPIIMUScaleLength (k_unSPIIMUScaleEndOffset - k_unSPIIMUScaleStartOffset + 1) + +#define k_unSPIIMUUserScaleStartOffset 0x8026 +#define k_unSPIIMUUserScaleEndOffset 0x8039 +#define k_unSPIIMUUserScaleLength (k_unSPIIMUUserScaleEndOffset - k_unSPIIMUUserScaleStartOffset + 1) + #pragma pack(1) typedef struct { @@ -266,6 +279,16 @@ typedef struct { Sint16 sMax; } axis[2]; } m_StickExtents[2]; + + struct IMUScaleData { + float fAccelScaleX; + float fAccelScaleY; + float fAccelScaleZ; + + float fGyroScaleX; + float fGyroScaleY; + float fGyroScaleZ; + } m_IMUScaleData; } SDL_DriverSwitch_Context; @@ -769,6 +792,72 @@ static SDL_bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx, Uint8 input_ return SDL_TRUE; } +static SDL_bool LoadIMUCalibration(SDL_DriverSwitch_Context* ctx) +{ + Uint8* pIMUScale; + SwitchSubcommandInputPacket_t* reply = NULL; + Sint16 sAccelRawX, sAccelRawY, sAccelRawZ, sGyroRawX, sGyroRawY, sGyroRawZ; + + /* Read Calibration Info */ + SwitchSPIOpData_t readParams; + readParams.unAddress = k_unSPIIMUScaleStartOffset; + readParams.ucLength = k_unSPIIMUScaleLength; + + if (!WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t*)&readParams, sizeof(readParams), &reply)) { + const float accelScale = SDL_STANDARD_GRAVITY / SWITCH_ACCEL_SCALE; + const float gyroScale = (float)M_PI / 180.0f / SWITCH_GYRO_SCALE; + + ctx->m_IMUScaleData.fAccelScaleX = accelScale; + ctx->m_IMUScaleData.fAccelScaleY = accelScale; + ctx->m_IMUScaleData.fAccelScaleZ = accelScale; + + ctx->m_IMUScaleData.fGyroScaleX = gyroScale; + ctx->m_IMUScaleData.fGyroScaleY = gyroScale; + ctx->m_IMUScaleData.fGyroScaleZ = gyroScale; + + return SDL_FALSE; + } + + /* IMU scale gives us multipliers for converting raw values to real world values */ + pIMUScale = reply->spiReadData.rgucReadData; + + sAccelRawX = ((pIMUScale[1] << 8) & 0xF00) | pIMUScale[0]; + sAccelRawY = ((pIMUScale[3] << 8) & 0xF00) | pIMUScale[2]; + sAccelRawZ = ((pIMUScale[5] << 8) & 0xF00) | pIMUScale[4]; + + sGyroRawX = ((pIMUScale[13] << 8) & 0xF00) | pIMUScale[12]; + sGyroRawY = ((pIMUScale[15] << 8) & 0xF00) | pIMUScale[14]; + sGyroRawZ = ((pIMUScale[17] << 8) & 0xF00) | pIMUScale[16]; + + /* Check for user calibration data. If it's present and set, it'll override the factory settings */ + readParams.unAddress = k_unSPIIMUUserScaleStartOffset; + readParams.ucLength = k_unSPIIMUUserScaleLength; + if (WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t*)&readParams, sizeof(readParams), &reply) && (pIMUScale[0] | pIMUScale[1] << 8) == 0xA1B2) { + pIMUScale = reply->spiReadData.rgucReadData; + + sAccelRawX = ((pIMUScale[3] << 8) & 0xF00) | pIMUScale[2]; + sAccelRawY = ((pIMUScale[5] << 8) & 0xF00) | pIMUScale[4]; + sAccelRawZ = ((pIMUScale[7] << 8) & 0xF00) | pIMUScale[6]; + + sGyroRawX = ((pIMUScale[15] << 8) & 0xF00) | pIMUScale[14]; + sGyroRawY = ((pIMUScale[17] << 8) & 0xF00) | pIMUScale[16]; + sGyroRawZ = ((pIMUScale[19] << 8) & 0xF00) | pIMUScale[18]; + } + + /* Accelerometer scale */ + ctx->m_IMUScaleData.fAccelScaleX = SWITCH_ACCEL_SCALE_MULT / (float)(SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawX) * SDL_STANDARD_GRAVITY; + ctx->m_IMUScaleData.fAccelScaleY = SWITCH_ACCEL_SCALE_MULT / (float)(SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawY) * SDL_STANDARD_GRAVITY; + ctx->m_IMUScaleData.fAccelScaleZ = SWITCH_ACCEL_SCALE_MULT / (float)(SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawZ) * SDL_STANDARD_GRAVITY; + + /* Gyro scale */ + ctx->m_IMUScaleData.fGyroScaleX = SWITCH_GYRO_SCALE_MULT / (float)(SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawX) * (float)M_PI / 180.0f; + ctx->m_IMUScaleData.fGyroScaleY = SWITCH_GYRO_SCALE_MULT / (float)(SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawY) * (float)M_PI / 180.0f; + ctx->m_IMUScaleData.fGyroScaleZ = SWITCH_GYRO_SCALE_MULT / (float)(SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawZ) * (float)M_PI / 180.0f; + + return SDL_TRUE; +} + + static Sint16 ApplyStickCalibrationCentered(SDL_DriverSwitch_Context *ctx, int nStick, int nAxis, Sint16 sRawValue, Sint16 sCenter) { sRawValue -= sCenter; @@ -914,6 +1003,11 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti goto error; } + if (!LoadIMUCalibration(ctx)) { + SDL_SetError("Couldn't load sensor calibration"); + goto error; + } + if (!SetVibrationEnabled(ctx, 1)) { SDL_SetError("Couldn't enable vibration"); goto error; @@ -1146,20 +1240,6 @@ HIDAPI_DriverSwitch_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joy return 0; } -static float -HIDAPI_DriverSwitch_ScaleGyro(Sint16 value) -{ - float result = (value / SWITCH_GYRO_SCALE) * (float)M_PI / 180.0f; - return result; -} - -static float -HIDAPI_DriverSwitch_ScaleAccel(Sint16 value) -{ - float result = (value / SWITCH_ACCEL_SCALE) * SDL_STANDARD_GRAVITY; - return result; -} - static void HandleInputOnlyControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_Context *ctx, SwitchInputOnlyControllerStatePacket_t *packet) { Sint16 axis; @@ -1357,13 +1437,13 @@ static void SendSensorUpdate(SDL_Joystick *joystick, SDL_DriverSwitch_Context *c * users will want consistent axis mappings across devices. */ if (type == SDL_SENSOR_GYRO) { - data[0] = -HIDAPI_DriverSwitch_ScaleGyro(values[1]); - data[1] = HIDAPI_DriverSwitch_ScaleGyro(values[2]); - data[2] = -HIDAPI_DriverSwitch_ScaleGyro(values[0]); + data[0] = -(ctx->m_IMUScaleData.fGyroScaleY * (float)values[1]); + data[1] = ctx->m_IMUScaleData.fGyroScaleZ * (float)values[2]; + data[2] = -(ctx->m_IMUScaleData.fGyroScaleX * (float)values[0]); } else { - data[0] = -HIDAPI_DriverSwitch_ScaleAccel(values[1]); - data[1] = HIDAPI_DriverSwitch_ScaleAccel(values[2]); - data[2] = -HIDAPI_DriverSwitch_ScaleAccel(values[0]); + data[0] = -(ctx->m_IMUScaleData.fAccelScaleY * (float)values[1]); + data[1] = ctx->m_IMUScaleData.fAccelScaleZ * (float)values[2]; + data[2] = -(ctx->m_IMUScaleData.fAccelScaleX * (float)values[0]); } /* Right Joy-Con flips some axes, so let's flip them back for consistency */ @@ -1440,20 +1520,20 @@ static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_C * LSB of connection nibble is USB/Switch connection status */ if (packet->controllerState.ucBatteryAndConnection & 0x1) { - joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED; + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_WIRED); } else { /* LSB of the battery nibble is used to report charging. * The battery level is reported from 0(empty)-8(full) */ int level = (packet->controllerState.ucBatteryAndConnection & 0xE0) >> 4; if (level == 0) { - joystick->epowerlevel = SDL_JOYSTICK_POWER_EMPTY; + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY); } else if (level <= 2) { - joystick->epowerlevel = SDL_JOYSTICK_POWER_LOW; + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW); } else if (level <= 6) { - joystick->epowerlevel = SDL_JOYSTICK_POWER_MEDIUM; + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM); } else { - joystick->epowerlevel = SDL_JOYSTICK_POWER_FULL; + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL); } } diff --git a/src/joystick/hidapi/SDL_hidapi_xbox360w.c b/src/joystick/hidapi/SDL_hidapi_xbox360w.c index e6e6171ab..91c15a73b 100644 --- a/src/joystick/hidapi/SDL_hidapi_xbox360w.c +++ b/src/joystick/hidapi/SDL_hidapi_xbox360w.c @@ -81,13 +81,13 @@ UpdatePowerLevel(SDL_Joystick *joystick, Uint8 level) float normalized_level = (float)level / 255.0f; if (normalized_level <= 0.05f) { - joystick->epowerlevel = SDL_JOYSTICK_POWER_EMPTY; + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY); } else if (normalized_level <= 0.20f) { - joystick->epowerlevel = SDL_JOYSTICK_POWER_LOW; + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW); } else if (normalized_level <= 0.70f) { - joystick->epowerlevel = SDL_JOYSTICK_POWER_MEDIUM; + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM); } else { - joystick->epowerlevel = SDL_JOYSTICK_POWER_FULL; + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL); } } diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c index f54b3c3f2..34542f92a 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick.c +++ b/src/joystick/hidapi/SDL_hidapijoystick.c @@ -783,6 +783,21 @@ HIDAPI_JoystickGetDeviceName(int device_index) return name; } +static const char * +HIDAPI_JoystickGetDevicePath(int device_index) +{ + SDL_HIDAPI_Device *device; + const char *path = NULL; + + device = HIDAPI_GetDeviceByIndex(device_index, NULL); + if (device) { + /* FIXME: The device could be freed after this path is returned... */ + path = device->path; + } + + return path; +} + static int HIDAPI_JoystickGetDevicePlayerIndex(int device_index) { @@ -1030,6 +1045,7 @@ SDL_JoystickDriver SDL_HIDAPI_JoystickDriver = HIDAPI_JoystickGetCount, HIDAPI_JoystickDetect, HIDAPI_JoystickGetDeviceName, + HIDAPI_JoystickGetDevicePath, HIDAPI_JoystickGetDevicePlayerIndex, HIDAPI_JoystickSetDevicePlayerIndex, HIDAPI_JoystickGetDeviceGUID, diff --git a/src/joystick/iphoneos/SDL_mfijoystick.m b/src/joystick/iphoneos/SDL_mfijoystick.m index 666c1c1cd..c55cf7887 100644 --- a/src/joystick/iphoneos/SDL_mfijoystick.m +++ b/src/joystick/iphoneos/SDL_mfijoystick.m @@ -335,11 +335,7 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle } 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; - } + /* The Backbone app uses share button */ if ((device->button_mask & (1 << SDL_CONTROLLER_BUTTON_MISC1)) != 0) { device->button_mask &= ~(1 << SDL_CONTROLLER_BUTTON_MISC1); --nbuttons; @@ -651,6 +647,12 @@ IOS_JoystickGetDeviceName(int device_index) return device ? device->name : "Unknown"; } +static const char * +IOS_JoystickGetDevicePath(int device_index) +{ + return NULL; +} + static int IOS_JoystickGetDevicePlayerIndex(int device_index) { @@ -739,7 +741,7 @@ IOS_JoystickOpen(SDL_Joystick *joystick, int device_index) } #ifdef ENABLE_MFI_SENSORS - if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) { + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { GCController *controller = joystick->hwdata->controller; GCMotion *motion = controller.motion; if (motion && motion.hasRotationRate) { @@ -752,7 +754,7 @@ IOS_JoystickOpen(SDL_Joystick *joystick, int device_index) #endif /* ENABLE_MFI_SENSORS */ #ifdef ENABLE_MFI_SYSTEM_GESTURE_STATE - if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) { + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { GCController *controller = joystick->hwdata->controller; for (id key in controller.physicalInputProfile.buttons) { GCControllerButtonInput *button = controller.physicalInputProfile.buttons[key]; @@ -964,7 +966,7 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) } #ifdef ENABLE_MFI_SENSORS - if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) { + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { GCMotion *motion = controller.motion; if (motion && motion.sensorsActive) { float data[3]; @@ -1057,7 +1059,7 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) } #ifdef ENABLE_MFI_BATTERY - if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) { + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { GCDeviceBattery *battery = controller.battery; if (battery) { SDL_JoystickPowerLevel ePowerLevel = SDL_JOYSTICK_POWER_UNKNOWN; @@ -1098,8 +1100,8 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) #ifdef ENABLE_MFI_RUMBLE @interface SDL_RumbleMotor : NSObject - @property(nonatomic,strong) CHHapticEngine *engine API_AVAILABLE(macos(11.0), ios(13.0), tvos(14.0)); - @property(nonatomic,strong) id player API_AVAILABLE(macos(11.0), ios(13.0), tvos(14.0)); + @property(nonatomic,strong) CHHapticEngine *engine API_AVAILABLE(macos(10.16), ios(13.0), tvos(14.0)); + @property(nonatomic,strong) id player API_AVAILABLE(macos(10.16), ios(13.0), tvos(14.0)); @property bool active; @end @@ -1109,7 +1111,7 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) -(void)cleanup { @autoreleasepool { - if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) { + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { if (self.player != nil) { [self.player cancelAndReturnError:nil]; self.player = nil; @@ -1125,7 +1127,7 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) -(int)setIntensity:(float)intensity { @autoreleasepool { - if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) { + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { NSError *error = nil; if (self.engine == nil) { @@ -1171,7 +1173,7 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) } } --(id) initWithController:(GCController*)controller locality:(GCHapticsLocality)locality API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) +-(id) initWithController:(GCController*)controller locality:(GCHapticsLocality)locality API_AVAILABLE(macos(10.16), ios(14.0), tvos(14.0)) { @autoreleasepool { self = [super init]; @@ -1271,7 +1273,7 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) static SDL_RumbleContext *IOS_JoystickInitRumble(GCController *controller) { @autoreleasepool { - if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) { + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { SDL_RumbleMotor *low_frequency_motor = [[SDL_RumbleMotor alloc] initWithController:controller locality:GCHapticsLocalityLeftHandle]; SDL_RumbleMotor *high_frequency_motor = [[SDL_RumbleMotor alloc] initWithController:controller locality:GCHapticsLocalityRightHandle]; SDL_RumbleMotor *left_trigger_motor = [[SDL_RumbleMotor alloc] initWithController:controller locality:GCHapticsLocalityLeftTrigger]; @@ -1299,7 +1301,7 @@ IOS_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 h return SDL_SetError("Controller is no longer connected"); } - if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) { + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { if (!device->rumble && device->controller && device->controller.haptics) { SDL_RumbleContext *rumble = IOS_JoystickInitRumble(device->controller); if (rumble) { @@ -1329,7 +1331,7 @@ IOS_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 ri return SDL_SetError("Controller is no longer connected"); } - if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) { + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { if (!device->rumble && device->controller && device->controller.haptics) { SDL_RumbleContext *rumble = IOS_JoystickInitRumble(device->controller); if (rumble) { @@ -1362,7 +1364,7 @@ IOS_JoystickGetCapabilities(SDL_Joystick *joystick) return 0; } - if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) { + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { GCController *controller = device->controller; #ifdef ENABLE_MFI_LIGHT if (controller.light) { @@ -1399,7 +1401,7 @@ IOS_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) return SDL_SetError("Controller is no longer connected"); } - if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) { + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { GCController *controller = device->controller; GCDeviceLight *light = controller.light; if (light) { @@ -1432,7 +1434,7 @@ IOS_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) return SDL_SetError("Controller is no longer connected"); } - if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) { + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { GCController *controller = device->controller; GCMotion *motion = controller.motion; if (motion) { @@ -1495,7 +1497,7 @@ IOS_JoystickClose(SDL_Joystick *joystick) controller.playerIndex = -1; #ifdef ENABLE_MFI_SYSTEM_GESTURE_STATE - if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *)) { + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { for (id key in controller.physicalInputProfile.buttons) { GCControllerButtonInput *button = controller.physicalInputProfile.buttons[key]; if ([button isBoundToSystemGesture]) { @@ -1593,7 +1595,7 @@ SDL_bool IOS_SupportedHIDDevice(IOHIDDeviceRef device) static void GetAppleSFSymbolsNameForElement(GCControllerElement *element, char *name) { - if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) { + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { if (element) { [element.sfSymbolsName getCString: name maxLength: 255 encoding: NSASCIIStringEncoding]; } @@ -1627,7 +1629,7 @@ IOS_GameControllerGetAppleSFSymbolsNameForButton(SDL_GameController *gamecontrol elementName[0] = '\0'; #if defined(SDL_JOYSTICK_MFI) && defined(ENABLE_PHYSICAL_INPUT_PROFILE) if (gamecontroller && SDL_GameControllerGetJoystick(gamecontroller)->driver == &SDL_IOS_JoystickDriver) { - if (@available(iOS 14.0, tvOS 14.0, macOS 11.0, *)) { + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { GCController *controller = SDL_GameControllerGetJoystick(gamecontroller)->hwdata->controller; if ([controller respondsToSelector:@selector(physicalInputProfile)]) { NSDictionary *elements = controller.physicalInputProfile.elements; @@ -1740,7 +1742,7 @@ IOS_GameControllerGetAppleSFSymbolsNameForAxis(SDL_GameController *gamecontrolle elementName[0] = '\0'; #if defined(SDL_JOYSTICK_MFI) && defined(ENABLE_PHYSICAL_INPUT_PROFILE) if (gamecontroller && SDL_GameControllerGetJoystick(gamecontroller)->driver == &SDL_IOS_JoystickDriver) { - if (@available(iOS 14.0, tvOS 14.0, macOS 11.0, *)) { + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { GCController *controller = SDL_GameControllerGetJoystick(gamecontroller)->hwdata->controller; if ([controller respondsToSelector:@selector(physicalInputProfile)]) { NSDictionary *elements = controller.physicalInputProfile.elements; @@ -1781,6 +1783,7 @@ SDL_JoystickDriver SDL_IOS_JoystickDriver = IOS_JoystickGetCount, IOS_JoystickDetect, IOS_JoystickGetDeviceName, + IOS_JoystickGetDevicePath, IOS_JoystickGetDevicePlayerIndex, IOS_JoystickSetDevicePlayerIndex, IOS_JoystickGetDeviceGUID, diff --git a/src/joystick/linux/SDL_sysjoystick.c b/src/joystick/linux/SDL_sysjoystick.c index a268c0d9b..307dd5642 100644 --- a/src/joystick/linux/SDL_sysjoystick.c +++ b/src/joystick/linux/SDL_sysjoystick.c @@ -82,6 +82,10 @@ #define DEBUG_INPUT_EVENTS 1 #endif +#if 0 +#define DEBUG_GAMEPAD_MAPPING 1 +#endif + typedef enum { ENUMERATION_UNSET, @@ -493,21 +497,6 @@ static void SteamControllerDisconnectedCallback(int device_instance) } } -#ifdef HAVE_INOTIFY -#ifdef HAVE_INOTIFY_INIT1 -static int SDL_inotify_init1(void) { - return inotify_init1(IN_NONBLOCK | IN_CLOEXEC); -} -#else -static int SDL_inotify_init1(void) { - int fd = inotify_init(); - if (fd < 0) return -1; - fcntl(fd, F_SETFL, O_NONBLOCK); - fcntl(fd, F_SETFD, FD_CLOEXEC); - return fd; -} -#endif - static int StrHasPrefix(const char *string, const char *prefix) { @@ -562,6 +551,21 @@ IsJoystickDeviceNode(const char *node) } } +#ifdef HAVE_INOTIFY +#ifdef HAVE_INOTIFY_INIT1 +static int SDL_inotify_init1(void) { + return inotify_init1(IN_NONBLOCK | IN_CLOEXEC); +} +#else +static int SDL_inotify_init1(void) { + int fd = inotify_init(); + if (fd < 0) return -1; + fcntl(fd, F_SETFL, O_NONBLOCK); + fcntl(fd, F_SETFD, FD_CLOEXEC); + return fd; +} +#endif + static void LINUX_InotifyJoystickDetect(void) { @@ -854,13 +858,18 @@ JoystickByDevIndex(int device_index) return item; } -/* Function to get the device-dependent name of a joystick */ static const char * LINUX_JoystickGetDeviceName(int device_index) { return JoystickByDevIndex(device_index)->name; } +static const char * +LINUX_JoystickGetDevicePath(int device_index) +{ + return JoystickByDevIndex(device_index)->path; +} + static int LINUX_JoystickGetDevicePlayerIndex(int device_index) { @@ -921,6 +930,37 @@ allocate_balldata(SDL_Joystick *joystick) return (0); } +static SDL_bool +GuessIfAxesAreDigitalHat(struct input_absinfo *absinfo_x, struct input_absinfo *absinfo_y) +{ + /* A "hat" is assumed to be a digital input with at most 9 possible states + * (3 per axis: negative/zero/positive), as opposed to a true "axis" which + * can report a continuous range of possible values. Unfortunately the Linux + * joystick interface makes no distinction between digital hat axes and any + * other continuous analog axis, so we have to guess. */ + + /* If both axes are missing, they're not anything. */ + if (!absinfo_x && !absinfo_y) + return SDL_FALSE; + + /* If the hint says so, treat all hats as digital. */ + if (SDL_GetHintBoolean(SDL_HINT_LINUX_DIGITAL_HATS, SDL_FALSE)) + return SDL_TRUE; + + /* If both axes have ranges constrained between -1 and 1, they're definitely digital. */ + if ((!absinfo_x || (absinfo_x->minimum == -1 && absinfo_x->maximum == 1)) && + (!absinfo_y || (absinfo_y->minimum == -1 && absinfo_y->maximum == 1))) + return SDL_TRUE; + + /* If both axes lack fuzz, flat, and resolution values, they're probably digital. */ + if ((!absinfo_x || (!absinfo_x->fuzz && !absinfo_x->flat && !absinfo_x->resolution)) && + (!absinfo_y || (!absinfo_y->fuzz && !absinfo_y->flat && !absinfo_y->resolution))) + return SDL_TRUE; + + /* Otherwise, treat them as analog. */ + return SDL_FALSE; +} + static void ConfigJoystick(SDL_Joystick *joystick, int fd) { @@ -931,6 +971,7 @@ ConfigJoystick(SDL_Joystick *joystick, int fd) unsigned long ffbit[NBITS(FF_MAX)] = { 0 }; Uint8 key_pam_size, abs_pam_size; SDL_bool use_deadzones = SDL_GetHintBoolean(SDL_HINT_LINUX_JOYSTICK_DEADZONES, SDL_FALSE); + SDL_bool use_hat_deadzones = SDL_GetHintBoolean(SDL_HINT_LINUX_HAT_DEADZONES, SDL_TRUE); /* See if this device uses the new unified event API */ if ((ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) && @@ -958,10 +999,45 @@ ConfigJoystick(SDL_Joystick *joystick, int fd) ++joystick->nbuttons; } } + for (i = ABS_HAT0X; i <= ABS_HAT3Y; i += 2) { + int hat_x = -1; + int hat_y = -1; + struct input_absinfo absinfo_x; + struct input_absinfo absinfo_y; + if (test_bit(i, absbit)) + hat_x = ioctl(fd, EVIOCGABS(i), &absinfo_x); + if (test_bit(i + 1, absbit)) + hat_y = ioctl(fd, EVIOCGABS(i + 1), &absinfo_y); + if (GuessIfAxesAreDigitalHat((hat_x < 0 ? (void*)0 : &absinfo_x), + (hat_y < 0 ? (void*)0 : &absinfo_y))) { + const int hat_index = (i - ABS_HAT0X) / 2; + struct hat_axis_correct *correct = &joystick->hwdata->hat_correct[hat_index]; +#ifdef DEBUG_INPUT_EVENTS + SDL_Log("Joystick has digital hat: #%d\n", hat_index); + if (hat_x >= 0) { + SDL_Log("X Values = { val:%d, min:%d, max:%d, fuzz:%d, flat:%d, res:%d }\n", + absinfo_x.value, absinfo_x.minimum, absinfo_x.maximum, + absinfo_x.fuzz, absinfo_x.flat, absinfo_x.resolution); + } + if (hat_y >= 0) { + SDL_Log("Y Values = { val:%d, min:%d, max:%d, fuzz:%d, flat:%d, res:%d }\n", + absinfo_y.value, absinfo_y.minimum, absinfo_y.maximum, + absinfo_y.fuzz, absinfo_y.flat, absinfo_y.resolution); + } +#endif /* DEBUG_INPUT_EVENTS */ + joystick->hwdata->hats_indices[hat_index] = joystick->nhats; + joystick->hwdata->has_hat[hat_index] = SDL_TRUE; + correct->use_deadzones = use_hat_deadzones; + correct->minimum[0] = (hat_x < 0) ? -1 : absinfo_x.minimum; + correct->maximum[0] = (hat_x < 0) ? 1 : absinfo_x.maximum; + correct->minimum[1] = (hat_y < 0) ? -1 : absinfo_y.minimum; + correct->maximum[1] = (hat_y < 0) ? 1 : absinfo_y.maximum; + ++joystick->nhats; + } + } for (i = 0; i < ABS_MAX; ++i) { - /* Skip hats */ - if (i == ABS_HAT0X) { - i = ABS_HAT3Y; + /* Skip digital hats */ + if (joystick->hwdata->has_hat[(i - ABS_HAT0X) / 2]) { continue; } if (test_bit(i, absbit)) { @@ -973,9 +1049,9 @@ ConfigJoystick(SDL_Joystick *joystick, int fd) } #ifdef DEBUG_INPUT_EVENTS SDL_Log("Joystick has absolute axis: 0x%.2x\n", i); - SDL_Log("Values = { %d, %d, %d, %d, %d }\n", + SDL_Log("Values = { val:%d, min:%d, max:%d, fuzz:%d, flat:%d, res:%d }\n", absinfo.value, absinfo.minimum, absinfo.maximum, - absinfo.fuzz, absinfo.flat); + absinfo.fuzz, absinfo.flat, absinfo.resolution); #endif /* DEBUG_INPUT_EVENTS */ joystick->hwdata->abs_map[i] = joystick->naxes; joystick->hwdata->has_abs[i] = SDL_TRUE; @@ -1003,24 +1079,6 @@ ConfigJoystick(SDL_Joystick *joystick, int fd) ++joystick->naxes; } } - for (i = ABS_HAT0X; i <= ABS_HAT3Y; i += 2) { - if (test_bit(i, absbit) || test_bit(i + 1, absbit)) { - struct input_absinfo absinfo; - int hat_index = (i - ABS_HAT0X) / 2; - - if (ioctl(fd, EVIOCGABS(i), &absinfo) < 0) { - continue; - } -#ifdef DEBUG_INPUT_EVENTS - SDL_Log("Joystick has hat %d\n", hat_index); - SDL_Log("Values = { %d, %d, %d, %d, %d }\n", - absinfo.value, absinfo.minimum, absinfo.maximum, - absinfo.fuzz, absinfo.flat); -#endif /* DEBUG_INPUT_EVENTS */ - joystick->hwdata->hats_indices[hat_index] = joystick->nhats++; - joystick->hwdata->has_hat[hat_index] = SDL_TRUE; - } - } if (test_bit(REL_X, relbit) || test_bit(REL_Y, relbit)) { ++joystick->nballs; } @@ -1066,14 +1124,19 @@ ConfigJoystick(SDL_Joystick *joystick, int fd) for (i = 0; i < abs_pam_size; ++i) { Uint8 code = joystick->hwdata->abs_pam[i]; + // TODO: is there any way to detect analog hats in advance via this API? if (code >= ABS_HAT0X && code <= ABS_HAT3Y) { int hat_index = (code - ABS_HAT0X) / 2; if (!joystick->hwdata->has_hat[hat_index]) { #ifdef DEBUG_INPUT_EVENTS - SDL_Log("Joystick has hat %d\n", hat_index); + SDL_Log("Joystick has digital hat: #%d\n", hat_index); #endif joystick->hwdata->hats_indices[hat_index] = joystick->nhats++; joystick->hwdata->has_hat[hat_index] = SDL_TRUE; + joystick->hwdata->hat_correct[hat_index].minimum[0] = -1; + joystick->hwdata->hat_correct[hat_index].maximum[0] = 1; + joystick->hwdata->hat_correct[hat_index].minimum[1] = -1; + joystick->hwdata->hat_correct[hat_index].maximum[1] = 1; } } else { #ifdef DEBUG_INPUT_EVENTS @@ -1272,26 +1335,48 @@ LINUX_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) } static void -HandleHat(SDL_Joystick *stick, Uint8 hat, int axis, int value) +HandleHat(SDL_Joystick *stick, int hatidx, int axis, int value) { + const int hatnum = stick->hwdata->hats_indices[hatidx]; struct hwdata_hat *the_hat; + struct hat_axis_correct *correct; const Uint8 position_map[3][3] = { {SDL_HAT_LEFTUP, SDL_HAT_UP, SDL_HAT_RIGHTUP}, {SDL_HAT_LEFT, SDL_HAT_CENTERED, SDL_HAT_RIGHT}, {SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN} }; - the_hat = &stick->hwdata->hats[hat]; + the_hat = &stick->hwdata->hats[hatnum]; + correct = &stick->hwdata->hat_correct[hatidx]; + /* Hopefully we detected any analog axes and left them as is rather than trying + * to use them as digital hats, but just in case, the deadzones here will + * prevent the slightest of twitches on an analog axis from registering as a hat + * movement. If the axes really are digital, this won't hurt since they should + * only ever be sending min, 0, or max anyway. */ if (value < 0) { - value = 0; - } else if (value == 0) { - value = 1; + if (value <= correct->minimum[axis]) { + correct->minimum[axis] = value; + value = 0; + } else if (!correct->use_deadzones || value < correct->minimum[axis] / 3) { + value = 0; + } else { + value = 1; + } } else if (value > 0) { - value = 2; + if (value >= correct->maximum[axis]) { + correct->maximum[axis] = value; + value = 2; + } else if (!correct->use_deadzones || value > correct->maximum[axis] / 3) { + value = 2; + } else { + value = 1; + } + } else { // value == 0 + value = 1; } if (value != the_hat->axis[axis]) { the_hat->axis[axis] = value; - SDL_PrivateJoystickHat(stick, hat, + SDL_PrivateJoystickHat(stick, hatnum, position_map[the_hat->axis[1]][the_hat->axis[0]]); } } @@ -1346,10 +1431,7 @@ PollAllValues(SDL_Joystick *joystick) /* Poll all axis */ for (i = ABS_X; i < ABS_MAX; i++) { - if (i == ABS_HAT0X) { /* we handle hats in the next loop, skip them for now. */ - i = ABS_HAT3Y; - continue; - } + /* We don't need to test for digital hats here, they won't have has_abs[] set */ if (joystick->hwdata->has_abs[i]) { if (ioctl(joystick->hwdata->fd, EVIOCGABS(i), &absinfo) >= 0) { absinfo.value = AxisCorrect(joystick, i, absinfo.value); @@ -1365,15 +1447,16 @@ PollAllValues(SDL_Joystick *joystick) } } - /* Poll all hats */ + /* Poll all digital hats */ for (i = ABS_HAT0X; i <= ABS_HAT3Y; i++) { const int baseaxis = i - ABS_HAT0X; const int hatidx = baseaxis / 2; SDL_assert(hatidx < SDL_arraysize(joystick->hwdata->has_hat)); + /* We don't need to test for analog axes here, they won't have has_hat[] set */ if (joystick->hwdata->has_hat[hatidx]) { if (ioctl(joystick->hwdata->fd, EVIOCGABS(i), &absinfo) >= 0) { const int hataxis = baseaxis % 2; - HandleHat(joystick, joystick->hwdata->hats_indices[hatidx], hataxis, absinfo.value); + HandleHat(joystick, hatidx, hataxis, absinfo.value); } } } @@ -1401,7 +1484,7 @@ static void HandleInputEvents(SDL_Joystick *joystick) { struct input_event events[32]; - int i, len, code; + int i, len, code, hat_index; if (joystick->hwdata->fresh) { PollAllValues(joystick); @@ -1436,9 +1519,11 @@ HandleInputEvents(SDL_Joystick *joystick) case ABS_HAT2Y: case ABS_HAT3X: case ABS_HAT3Y: - code -= ABS_HAT0X; - HandleHat(joystick, joystick->hwdata->hats_indices[code / 2], code % 2, events[i].value); - break; + hat_index = (code - ABS_HAT0X) / 2; + if (joystick->hwdata->has_hat[hat_index]) { + HandleHat(joystick, hat_index, code % 2, events[i].value); + break; + } default: events[i].value = AxisCorrect(joystick, code, events[i].value); SDL_PrivateJoystickAxis(joystick, @@ -1491,7 +1576,7 @@ static void HandleClassicEvents(SDL_Joystick *joystick) { struct js_event events[32]; - int i, len, code; + int i, len, code, hat_index; joystick->hwdata->fresh = SDL_FALSE; while ((len = read(joystick->hwdata->fd, events, (sizeof events))) > 0) { @@ -1515,9 +1600,11 @@ HandleClassicEvents(SDL_Joystick *joystick) case ABS_HAT2Y: case ABS_HAT3X: case ABS_HAT3Y: - code -= ABS_HAT0X; - HandleHat(joystick, joystick->hwdata->hats_indices[code / 2], code % 2, events[i].value); - break; + hat_index = (code - ABS_HAT0X) / 2; + if (joystick->hwdata->has_hat[hat_index]) { + HandleHat(joystick, hat_index, code % 2, events[i].value); + break; + } default: SDL_PrivateJoystickAxis(joystick, joystick->hwdata->abs_map[code], @@ -1623,10 +1710,14 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) { SDL_Joystick *joystick; SDL_joylist_item *item = JoystickByDevIndex(device_index); + unsigned int mapped; if (item->checked_mapping) { if (item->mapping) { SDL_memcpy(out, item->mapping, sizeof(*out)); +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Prior mapping for device %d", device_index); +#endif return SDL_TRUE; } else { return SDL_FALSE; @@ -1674,11 +1765,17 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) if (joystick->hwdata->has_key[BTN_A]) { out->a.kind = EMappingKind_Button; out->a.target = joystick->hwdata->key_map[BTN_A]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped A to button %d (BTN_A)", out->a.target); +#endif } if (joystick->hwdata->has_key[BTN_B]) { out->b.kind = EMappingKind_Button; out->b.target = joystick->hwdata->key_map[BTN_B]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped B to button %d (BTN_B)", out->b.target); +#endif } /* Xbox controllers use BTN_X and BTN_Y, and PS4 controllers use BTN_WEST and BTN_NORTH */ @@ -1686,47 +1783,74 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) if (joystick->hwdata->has_key[BTN_WEST]) { out->x.kind = EMappingKind_Button; out->x.target = joystick->hwdata->key_map[BTN_WEST]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped X to button %d (BTN_WEST)", out->x.target); +#endif } if (joystick->hwdata->has_key[BTN_NORTH]) { out->y.kind = EMappingKind_Button; out->y.target = joystick->hwdata->key_map[BTN_NORTH]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped Y to button %d (BTN_NORTH)", out->y.target); +#endif } } else { if (joystick->hwdata->has_key[BTN_X]) { out->x.kind = EMappingKind_Button; out->x.target = joystick->hwdata->key_map[BTN_X]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped X to button %d (BTN_X)", out->x.target); +#endif } if (joystick->hwdata->has_key[BTN_Y]) { out->y.kind = EMappingKind_Button; out->y.target = joystick->hwdata->key_map[BTN_Y]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped Y to button %d (BTN_Y)", out->y.target); +#endif } } if (joystick->hwdata->has_key[BTN_SELECT]) { out->back.kind = EMappingKind_Button; out->back.target = joystick->hwdata->key_map[BTN_SELECT]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped BACK to button %d (BTN_SELECT)", out->back.target); +#endif } if (joystick->hwdata->has_key[BTN_START]) { out->start.kind = EMappingKind_Button; out->start.target = joystick->hwdata->key_map[BTN_START]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped START to button %d (BTN_START)", out->start.target); +#endif } if (joystick->hwdata->has_key[BTN_THUMBL]) { out->leftstick.kind = EMappingKind_Button; out->leftstick.target = joystick->hwdata->key_map[BTN_THUMBL]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped LEFTSTICK to button %d (BTN_THUMBL)", out->leftstick.target); +#endif } if (joystick->hwdata->has_key[BTN_THUMBR]) { out->rightstick.kind = EMappingKind_Button; out->rightstick.target = joystick->hwdata->key_map[BTN_THUMBR]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped RIGHTSTICK to button %d (BTN_THUMBR)", out->rightstick.target); +#endif } if (joystick->hwdata->has_key[BTN_MODE]) { out->guide.kind = EMappingKind_Button; out->guide.target = joystick->hwdata->key_map[BTN_MODE]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped GUIDE to button %d (BTN_MODE)", out->guide.target); +#endif } /* @@ -1734,84 +1858,191 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) can be digital, or analog, or both at the same time. */ - /* Prefer digital shoulder buttons, but settle for analog if missing. */ + /* Prefer digital shoulder buttons, but settle for digital or analog hat. */ + mapped = 0; + if (joystick->hwdata->has_key[BTN_TL]) { out->leftshoulder.kind = EMappingKind_Button; out->leftshoulder.target = joystick->hwdata->key_map[BTN_TL]; + mapped |= 0x1; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped LEFTSHOULDER to button %d (BTN_TL)", out->leftshoulder.target); +#endif } if (joystick->hwdata->has_key[BTN_TR]) { out->rightshoulder.kind = EMappingKind_Button; out->rightshoulder.target = joystick->hwdata->key_map[BTN_TR]; + mapped |= 0x2; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped RIGHTSHOULDER to button %d (BTN_TR)", out->rightshoulder.target); +#endif } - if (joystick->hwdata->has_hat[1] && /* Check if ABS_HAT1{X, Y} is available. */ - (!joystick->hwdata->has_key[BTN_TL] || !joystick->hwdata->has_key[BTN_TR])) { + if (mapped != 0x3 && joystick->hwdata->has_hat[1]) { int hat = joystick->hwdata->hats_indices[1] << 4; out->leftshoulder.kind = EMappingKind_Hat; out->rightshoulder.kind = EMappingKind_Hat; out->leftshoulder.target = hat | 0x4; out->rightshoulder.target = hat | 0x2; + mapped |= 0x3; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped LEFT+RIGHTSHOULDER to hat 1 (ABS_HAT1X, ABS_HAT1Y)"); +#endif } - /* Prefer analog triggers, but settle for digital if missing. */ - if (joystick->hwdata->has_hat[2]) { /* Check if ABS_HAT2{X,Y} is available. */ + if (!(mapped & 0x1) && joystick->hwdata->has_abs[ABS_HAT1Y]) { + out->leftshoulder.kind = EMappingKind_Axis; + out->leftshoulder.target = joystick->hwdata->abs_map[ABS_HAT1Y]; + mapped |= 0x1; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped LEFTSHOULDER to axis %d (ABS_HAT1Y)", out->leftshoulder.target); +#endif + } + + if (!(mapped & 0x2) && joystick->hwdata->has_abs[ABS_HAT1X]) { + out->rightshoulder.kind = EMappingKind_Axis; + out->rightshoulder.target = joystick->hwdata->abs_map[ABS_HAT1X]; + mapped |= 0x2; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped RIGHTSHOULDER to axis %d (ABS_HAT1X)", out->rightshoulder.target); +#endif + } + + /* Prefer analog triggers, but settle for digital hat or buttons. */ + mapped = 0; + + if (joystick->hwdata->has_abs[ABS_HAT2Y]) { + out->lefttrigger.kind = EMappingKind_Axis; + out->lefttrigger.target = joystick->hwdata->abs_map[ABS_HAT2Y]; + mapped |= 0x1; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped LEFTTRIGGER to axis %d (ABS_HAT2Y)", out->lefttrigger.target); +#endif + } else if (joystick->hwdata->has_abs[ABS_Z]) { + out->lefttrigger.kind = EMappingKind_Axis; + out->lefttrigger.target = joystick->hwdata->abs_map[ABS_Z]; + mapped |= 0x1; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped LEFTTRIGGER to axis %d (ABS_Z)", out->lefttrigger.target); +#endif + } + + if (joystick->hwdata->has_abs[ABS_HAT2X]) { + out->righttrigger.kind = EMappingKind_Axis; + out->righttrigger.target = joystick->hwdata->abs_map[ABS_HAT2X]; + mapped |= 0x2; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped RIGHTTRIGGER to axis %d (ABS_HAT2X)", out->righttrigger.target); +#endif + } else if (joystick->hwdata->has_abs[ABS_RZ]) { + out->righttrigger.kind = EMappingKind_Axis; + out->righttrigger.target = joystick->hwdata->abs_map[ABS_RZ]; + mapped |= 0x2; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped RIGHTTRIGGER to axis %d (ABS_RZ)", out->righttrigger.target); +#endif + } + + if (mapped != 0x3 && joystick->hwdata->has_hat[2]) { int hat = joystick->hwdata->hats_indices[2] << 4; out->lefttrigger.kind = EMappingKind_Hat; out->righttrigger.kind = EMappingKind_Hat; out->lefttrigger.target = hat | 0x4; out->righttrigger.target = hat | 0x2; - } else { - if (joystick->hwdata->has_abs[ABS_Z]) { - out->lefttrigger.kind = EMappingKind_Axis; - out->lefttrigger.target = joystick->hwdata->abs_map[ABS_Z]; - } else if (joystick->hwdata->has_key[BTN_TL2]) { - out->lefttrigger.kind = EMappingKind_Button; - out->lefttrigger.target = joystick->hwdata->key_map[BTN_TL2]; - } - - if (joystick->hwdata->has_abs[ABS_RZ]) { - out->righttrigger.kind = EMappingKind_Axis; - out->righttrigger.target = joystick->hwdata->abs_map[ABS_RZ]; - } else if (joystick->hwdata->has_key[BTN_TR2]) { - out->righttrigger.kind = EMappingKind_Button; - out->righttrigger.target = joystick->hwdata->key_map[BTN_TR2]; - } + mapped |= 0x3; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped LEFT+RIGHTTRIGGER to hat 2 (ABS_HAT2X, ABS_HAT2Y)"); +#endif } - /* Prefer digital D-Pad, but settle for analog if missing. */ + if (!(mapped & 0x1) && joystick->hwdata->has_key[BTN_TL2]) { + out->lefttrigger.kind = EMappingKind_Button; + out->lefttrigger.target = joystick->hwdata->key_map[BTN_TL2]; + mapped |= 0x1; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped LEFTTRIGGER to button %d (BTN_TL2)", out->lefttrigger.target); +#endif + } + + if (!(mapped & 0x2) && joystick->hwdata->has_key[BTN_TR2]) { + out->righttrigger.kind = EMappingKind_Button; + out->righttrigger.target = joystick->hwdata->key_map[BTN_TR2]; + mapped |= 0x2; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped RIGHTTRIGGER to button %d (BTN_TR2)", out->righttrigger.target); +#endif + } + + /* Prefer digital D-Pad buttons, but settle for digital or analog hat. */ + mapped = 0; + if (joystick->hwdata->has_key[BTN_DPAD_UP]) { out->dpup.kind = EMappingKind_Button; out->dpup.target = joystick->hwdata->key_map[BTN_DPAD_UP]; + mapped |= 0x1; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped DPUP to button %d (BTN_DPAD_UP)", out->dpup.target); +#endif } if (joystick->hwdata->has_key[BTN_DPAD_DOWN]) { out->dpdown.kind = EMappingKind_Button; out->dpdown.target = joystick->hwdata->key_map[BTN_DPAD_DOWN]; + mapped |= 0x2; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped DPDOWN to button %d (BTN_DPAD_DOWN)", out->dpdown.target); +#endif } if (joystick->hwdata->has_key[BTN_DPAD_LEFT]) { out->dpleft.kind = EMappingKind_Button; out->dpleft.target = joystick->hwdata->key_map[BTN_DPAD_LEFT]; + mapped |= 0x4; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped DPLEFT to button %d (BTN_DPAD_LEFT)", out->dpleft.target); +#endif } if (joystick->hwdata->has_key[BTN_DPAD_RIGHT]) { out->dpright.kind = EMappingKind_Button; out->dpright.target = joystick->hwdata->key_map[BTN_DPAD_RIGHT]; + mapped |= 0x8; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped DPRIGHT to button %d (BTN_DPAD_RIGHT)", out->dpright.target); +#endif } - if (joystick->hwdata->has_hat[0] && /* Check if ABS_HAT0{X,Y} is available. */ - (!joystick->hwdata->has_key[BTN_DPAD_LEFT] || !joystick->hwdata->has_key[BTN_DPAD_RIGHT] || - !joystick->hwdata->has_key[BTN_DPAD_UP] || !joystick->hwdata->has_key[BTN_DPAD_DOWN])) { - int hat = joystick->hwdata->hats_indices[0] << 4; - out->dpleft.kind = EMappingKind_Hat; - out->dpright.kind = EMappingKind_Hat; - out->dpup.kind = EMappingKind_Hat; - out->dpdown.kind = EMappingKind_Hat; - out->dpleft.target = hat | 0x8; - out->dpright.target = hat | 0x2; - out->dpup.target = hat | 0x1; - out->dpdown.target = hat | 0x4; + if (mapped != 0xF) { + if (joystick->hwdata->has_hat[0]) { + int hat = joystick->hwdata->hats_indices[0] << 4; + out->dpleft.kind = EMappingKind_Hat; + out->dpright.kind = EMappingKind_Hat; + out->dpup.kind = EMappingKind_Hat; + out->dpdown.kind = EMappingKind_Hat; + out->dpleft.target = hat | 0x8; + out->dpright.target = hat | 0x2; + out->dpup.target = hat | 0x1; + out->dpdown.target = hat | 0x4; + mapped |= 0xF; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped DPUP+DOWN+LEFT+RIGHT to hat 0 (ABS_HAT0X, ABS_HAT0Y)"); +#endif + } else if (joystick->hwdata->has_abs[ABS_HAT0X] && joystick->hwdata->has_abs[ABS_HAT0Y]) { + out->dpleft.kind = EMappingKind_Axis; + out->dpright.kind = EMappingKind_Axis; + out->dpup.kind = EMappingKind_Axis; + out->dpdown.kind = EMappingKind_Axis; + out->dpleft.target = joystick->hwdata->abs_map[ABS_HAT0X]; + out->dpright.target = joystick->hwdata->abs_map[ABS_HAT0X]; + out->dpup.target = joystick->hwdata->abs_map[ABS_HAT0Y]; + out->dpdown.target = joystick->hwdata->abs_map[ABS_HAT0Y]; + mapped |= 0xF; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped DPUP+DOWN to axis %d (ABS_HAT0Y)", out->dpup.target); + SDL_Log("Mapped DPLEFT+RIGHT to axis %d (ABS_HAT0X)", out->dpleft.target); +#endif + } } if (joystick->hwdata->has_abs[ABS_X] && joystick->hwdata->has_abs[ABS_Y]) { @@ -1819,6 +2050,10 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) out->lefty.kind = EMappingKind_Axis; out->leftx.target = joystick->hwdata->abs_map[ABS_X]; out->lefty.target = joystick->hwdata->abs_map[ABS_Y]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped LEFTX to axis %d (ABS_X)", out->leftx.target); + SDL_Log("Mapped LEFTY to axis %d (ABS_Y)", out->lefty.target); +#endif } if (joystick->hwdata->has_abs[ABS_RX] && joystick->hwdata->has_abs[ABS_RY]) { @@ -1826,6 +2061,10 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) out->righty.kind = EMappingKind_Axis; out->rightx.target = joystick->hwdata->abs_map[ABS_RX]; out->righty.target = joystick->hwdata->abs_map[ABS_RY]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped RIGHTX to axis %d (ABS_RX)", out->rightx.target); + SDL_Log("Mapped RIGHTY to axis %d (ABS_RY)", out->righty.target); +#endif } LINUX_JoystickClose(joystick); @@ -1836,6 +2075,9 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) if (item->mapping) { SDL_memcpy(item->mapping, out, sizeof(*out)); } +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Generated mapping for device %d", device_index); +#endif return SDL_TRUE; } @@ -1846,6 +2088,7 @@ SDL_JoystickDriver SDL_LINUX_JoystickDriver = LINUX_JoystickGetCount, LINUX_JoystickDetect, LINUX_JoystickGetDeviceName, + LINUX_JoystickGetDevicePath, LINUX_JoystickGetDevicePlayerIndex, LINUX_JoystickSetDevicePlayerIndex, LINUX_JoystickGetDeviceGUID, diff --git a/src/joystick/linux/SDL_sysjoystick_c.h b/src/joystick/linux/SDL_sysjoystick_c.h index 49b8686d0..f0e27b9ca 100644 --- a/src/joystick/linux/SDL_sysjoystick_c.h +++ b/src/joystick/linux/SDL_sysjoystick_c.h @@ -83,6 +83,12 @@ struct joystick_hwdata /* 4 = (ABS_HAT3X-ABS_HAT0X)/2 (see input-event-codes.h in kernel) */ int hats_indices[4]; SDL_bool has_hat[4]; + struct hat_axis_correct + { + SDL_bool use_deadzones; + int minimum[2]; + int maximum[2]; + } hat_correct[4]; /* Set when gamepad is pending removal due to ENODEV read error */ SDL_bool gone; diff --git a/src/joystick/os2/SDL_os2joystick.c b/src/joystick/os2/SDL_os2joystick.c index 00b7fc554..1c292ff4d 100644 --- a/src/joystick/os2/SDL_os2joystick.c +++ b/src/joystick/os2/SDL_os2joystick.c @@ -377,15 +377,17 @@ static void OS2_JoystickDetect(void) { } -/***********************************************************/ -/* Function to get the device-dependent name of a joystick */ -/***********************************************************/ static const char *OS2_JoystickGetDeviceName(int device_index) { /* No need to verify if device exists, already done in upper layer */ return SYS_JoyData[device_index].szDeviceName; } +static const char *OS2_JoystickGetDevicePath(int device_index) +{ + return NULL; +} + static int OS2_JoystickGetDevicePlayerIndex(int device_index) { return -1; @@ -779,6 +781,7 @@ SDL_JoystickDriver SDL_OS2_JoystickDriver = OS2_NumJoysticks, OS2_JoystickDetect, OS2_JoystickGetDeviceName, + OS2_JoystickGetDevicePath, OS2_JoystickGetDevicePlayerIndex, OS2_JoystickSetDevicePlayerIndex, OS2_JoystickGetDeviceGUID, diff --git a/src/joystick/psp/SDL_sysjoystick.c b/src/joystick/psp/SDL_sysjoystick.c index d71979560..a5422592b 100644 --- a/src/joystick/psp/SDL_sysjoystick.c +++ b/src/joystick/psp/SDL_sysjoystick.c @@ -142,7 +142,6 @@ static void PSP_JoystickDetect(void) } #if 0 -/* Function to get the device-dependent name of a joystick */ static const char *PSP_JoystickName(int idx) { if (idx == 0) return "PSP controller"; @@ -151,12 +150,16 @@ static const char *PSP_JoystickName(int idx) } #endif -/* Function to get the device-dependent name of a joystick */ static const char *PSP_JoystickGetDeviceName(int device_index) { return "PSP builtin joypad"; } +static const char *PSP_JoystickGetDevicePath(int device_index) +{ + return NULL; +} + static int PSP_JoystickGetDevicePlayerIndex(int device_index) { return -1; @@ -304,6 +307,7 @@ SDL_JoystickDriver SDL_PSP_JoystickDriver = PSP_NumJoysticks, PSP_JoystickDetect, PSP_JoystickGetDeviceName, + PSP_JoystickGetDevicePath, PSP_JoystickGetDevicePlayerIndex, PSP_JoystickSetDevicePlayerIndex, PSP_JoystickGetDeviceGUID, diff --git a/src/joystick/virtual/SDL_virtualjoystick.c b/src/joystick/virtual/SDL_virtualjoystick.c index 508dd80f9..273c75e5a 100644 --- a/src/joystick/virtual/SDL_virtualjoystick.c +++ b/src/joystick/virtual/SDL_virtualjoystick.c @@ -24,11 +24,11 @@ /* This is the virtual implementation of the SDL joystick API */ +#include "SDL_endian.h" #include "SDL_virtualjoystick_c.h" #include "../SDL_sysjoystick.h" #include "../SDL_joystick_c.h" -extern SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver; static joystick_hwdata * g_VJoys = NULL; @@ -56,18 +56,6 @@ VIRTUAL_FreeHWData(joystick_hwdata *hwdata) if (!hwdata) { return; } - if (hwdata->axes) { - SDL_free((void *)hwdata->axes); - hwdata->axes = NULL; - } - if (hwdata->buttons) { - SDL_free((void *)hwdata->buttons); - hwdata->buttons = NULL; - } - if (hwdata->hats) { - SDL_free(hwdata->hats); - hwdata->hats = NULL; - } /* Remove hwdata from SDL-global list */ while (cur) { @@ -83,51 +71,170 @@ VIRTUAL_FreeHWData(joystick_hwdata *hwdata) cur = cur->next; } + if (hwdata->joystick) { + hwdata->joystick->hwdata = NULL; + hwdata->joystick = NULL; + } + if (hwdata->name) { + SDL_free(hwdata->name); + hwdata->name = NULL; + } + if (hwdata->axes) { + SDL_free((void *)hwdata->axes); + hwdata->axes = NULL; + } + if (hwdata->buttons) { + SDL_free((void *)hwdata->buttons); + hwdata->buttons = NULL; + } + if (hwdata->hats) { + SDL_free(hwdata->hats); + hwdata->hats = NULL; + } SDL_free(hwdata); } int -SDL_JoystickAttachVirtualInner(SDL_JoystickType type, - int naxes, - int nbuttons, - int nhats) +SDL_JoystickAttachVirtualInner(const SDL_VirtualJoystickDesc *desc) { joystick_hwdata *hwdata = NULL; int device_index = -1; + const char *name = NULL; + Uint16 *guid16; + int axis_triggerleft = -1; + int axis_triggerright = -1; + + if (!desc) { + return SDL_InvalidParamError("desc"); + } + if (desc->version != SDL_VIRTUAL_JOYSTICK_DESC_VERSION) { + /* Is this an old version that we can support? */ + return SDL_SetError("Unsupported virtual joystick description version %d", desc->version); + } hwdata = SDL_calloc(1, sizeof(joystick_hwdata)); if (!hwdata) { VIRTUAL_FreeHWData(hwdata); return SDL_OutOfMemory(); } + SDL_memcpy(&hwdata->desc, desc, sizeof(*desc)); - hwdata->naxes = naxes; - hwdata->nbuttons = nbuttons; - hwdata->nhats = nhats; - hwdata->name = "Virtual Joystick"; + if (hwdata->desc.name) { + name = hwdata->desc.name; + } else { + switch (hwdata->desc.type) { + case SDL_JOYSTICK_TYPE_GAMECONTROLLER: + name = "Virtual Controller"; + break; + case SDL_JOYSTICK_TYPE_WHEEL: + name = "Virtual Wheel"; + break; + case SDL_JOYSTICK_TYPE_ARCADE_STICK: + name = "Virtual Arcade Stick"; + break; + case SDL_JOYSTICK_TYPE_FLIGHT_STICK: + name = "Virtual Flight Stick"; + break; + case SDL_JOYSTICK_TYPE_DANCE_PAD: + name = "Virtual Dance Pad"; + break; + case SDL_JOYSTICK_TYPE_GUITAR: + name = "Virtual Guitar"; + break; + case SDL_JOYSTICK_TYPE_DRUM_KIT: + name = "Virtual Drum Kit"; + break; + case SDL_JOYSTICK_TYPE_ARCADE_PAD: + name = "Virtual Arcade Pad"; + break; + case SDL_JOYSTICK_TYPE_THROTTLE: + name = "Virtual Throttle"; + break; + default: + name = "Virtual Joystick"; + break; + } + } + hwdata->name = SDL_strdup(name); + + if (hwdata->desc.type == SDL_JOYSTICK_TYPE_GAMECONTROLLER) { + int i, axis; + + if (hwdata->desc.button_mask == 0) { + for (i = 0; i < hwdata->desc.nbuttons && i < sizeof(hwdata->desc.button_mask)*8; ++i) { + hwdata->desc.button_mask |= (1 << i); + } + } + + if (hwdata->desc.axis_mask == 0) { + if (hwdata->desc.naxes >= 2) { + hwdata->desc.axis_mask |= ((1 << SDL_CONTROLLER_AXIS_LEFTX) | (1 << SDL_CONTROLLER_AXIS_LEFTY)); + } + if (hwdata->desc.naxes >= 4) { + hwdata->desc.axis_mask |= ((1 << SDL_CONTROLLER_AXIS_RIGHTX) | (1 << SDL_CONTROLLER_AXIS_RIGHTY)); + } + if (hwdata->desc.naxes >= 6) { + hwdata->desc.axis_mask |= ((1 << SDL_CONTROLLER_AXIS_TRIGGERLEFT) | (1 << SDL_CONTROLLER_AXIS_TRIGGERRIGHT)); + } + } + + /* Find the trigger axes */ + axis = 0; + for (i = 0; axis < hwdata->desc.naxes && i < SDL_CONTROLLER_AXIS_MAX; ++i) { + if (hwdata->desc.axis_mask & (1 << i)) { + if (i == SDL_CONTROLLER_AXIS_TRIGGERLEFT) { + axis_triggerleft = axis; + } + if (i == SDL_CONTROLLER_AXIS_TRIGGERRIGHT) { + axis_triggerright = axis; + } + ++axis; + } + } + } + + /* We only need 16 bits for each of these; space them out to fill 128. */ + /* Byteswap so devices get same GUID on little/big endian platforms. */ + guid16 = (Uint16 *)hwdata->guid.data; + *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_VIRTUAL); + *guid16++ = 0; + *guid16++ = SDL_SwapLE16(hwdata->desc.vendor_id); + *guid16++ = 0; + *guid16++ = SDL_SwapLE16(hwdata->desc.product_id); + *guid16++ = 0; + *guid16++ = 0; + *guid16++ = 0; /* This will be overwritten below with the virtual controller signature */ /* Note that this is a Virtual device and what subtype it is */ hwdata->guid.data[14] = 'v'; - hwdata->guid.data[15] = (Uint8)type; + hwdata->guid.data[15] = (Uint8)hwdata->desc.type; /* Allocate fields for different control-types */ - if (naxes > 0) { - hwdata->axes = SDL_calloc(naxes, sizeof(Sint16)); + if (hwdata->desc.naxes > 0) { + hwdata->axes = SDL_calloc(hwdata->desc.naxes, sizeof(Sint16)); if (!hwdata->axes) { VIRTUAL_FreeHWData(hwdata); return SDL_OutOfMemory(); } + + /* Trigger axes are at minimum value at rest */ + if (axis_triggerleft >= 0) { + hwdata->axes[axis_triggerleft] = SDL_JOYSTICK_AXIS_MIN; + } + if (axis_triggerright >= 0) { + hwdata->axes[axis_triggerright] = SDL_JOYSTICK_AXIS_MIN; + } } - if (nbuttons > 0) { - hwdata->buttons = SDL_calloc(nbuttons, sizeof(Uint8)); + if (hwdata->desc.nbuttons > 0) { + hwdata->buttons = SDL_calloc(hwdata->desc.nbuttons, sizeof(Uint8)); if (!hwdata->buttons) { VIRTUAL_FreeHWData(hwdata); return SDL_OutOfMemory(); } } - if (nhats > 0) { - hwdata->hats = SDL_calloc(nhats, sizeof(Uint8)); + if (hwdata->desc.nhats > 0) { + hwdata->hats = SDL_calloc(hwdata->desc.nhats, sizeof(Uint8)); if (!hwdata->hats) { VIRTUAL_FreeHWData(hwdata); return SDL_OutOfMemory(); @@ -138,8 +245,16 @@ SDL_JoystickAttachVirtualInner(SDL_JoystickType type, hwdata->instance_id = SDL_GetNextJoystickInstanceID(); /* Add virtual joystick to SDL-global lists */ - hwdata->next = g_VJoys; - g_VJoys = hwdata; + if (g_VJoys) { + joystick_hwdata *last; + + for (last = g_VJoys; last->next; last = last->next) { + continue; + } + last->next = hwdata; + } else { + g_VJoys = hwdata; + } SDL_PrivateJoystickAdded(hwdata->instance_id); /* Return the new virtual-device's index */ @@ -176,7 +291,7 @@ SDL_JoystickSetVirtualAxisInner(SDL_Joystick *joystick, int axis, Sint16 value) } hwdata = (joystick_hwdata *)joystick->hwdata; - if (axis < 0 || axis >= hwdata->naxes) { + if (axis < 0 || axis >= hwdata->desc.naxes) { SDL_UnlockJoysticks(); return SDL_SetError("Invalid axis index"); } @@ -201,7 +316,7 @@ SDL_JoystickSetVirtualButtonInner(SDL_Joystick *joystick, int button, Uint8 valu } hwdata = (joystick_hwdata *)joystick->hwdata; - if (button < 0 || button >= hwdata->nbuttons) { + if (button < 0 || button >= hwdata->desc.nbuttons) { SDL_UnlockJoysticks(); return SDL_SetError("Invalid button index"); } @@ -226,7 +341,7 @@ SDL_JoystickSetVirtualHatInner(SDL_Joystick *joystick, int hat, Uint8 value) } hwdata = (joystick_hwdata *)joystick->hwdata; - if (hat < 0 || hat >= hwdata->nhats) { + if (hat < 0 || hat >= hwdata->desc.nhats) { SDL_UnlockJoysticks(); return SDL_SetError("Invalid hat index"); } @@ -271,7 +386,14 @@ VIRTUAL_JoystickGetDeviceName(int device_index) if (!hwdata) { return NULL; } - return hwdata->name ? hwdata->name : ""; + return hwdata->name; +} + + +static const char * +VIRTUAL_JoystickGetDevicePath(int device_index) +{ + return NULL; } @@ -285,6 +407,11 @@ VIRTUAL_JoystickGetDevicePlayerIndex(int device_index) static void VIRTUAL_JoystickSetDevicePlayerIndex(int device_index, int player_index) { + joystick_hwdata *hwdata = VIRTUAL_HWDataForIndex(device_index); + + if (hwdata && hwdata->desc.SetPlayerIndex) { + hwdata->desc.SetPlayerIndex(hwdata->desc.userdata, player_index); + } } @@ -319,15 +446,12 @@ VIRTUAL_JoystickOpen(SDL_Joystick *joystick, int device_index) if (!hwdata) { return SDL_SetError("No such device"); } - if (hwdata->opened) { - return SDL_SetError("Joystick already opened"); - } joystick->instance_id = hwdata->instance_id; joystick->hwdata = hwdata; - joystick->naxes = hwdata->naxes; - joystick->nbuttons = hwdata->nbuttons; - joystick->nhats = hwdata->nhats; - hwdata->opened = SDL_TRUE; + joystick->naxes = hwdata->desc.naxes; + joystick->nbuttons = hwdata->desc.nbuttons; + joystick->nhats = hwdata->desc.nhats; + hwdata->joystick = joystick; return 0; } @@ -335,33 +459,99 @@ VIRTUAL_JoystickOpen(SDL_Joystick *joystick, int device_index) static int VIRTUAL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) { - return SDL_Unsupported(); + int result; + + if (joystick->hwdata) { + joystick_hwdata *hwdata = joystick->hwdata; + if (hwdata->desc.Rumble) { + result = hwdata->desc.Rumble(hwdata->desc.userdata, low_frequency_rumble, high_frequency_rumble); + } else { + result = SDL_Unsupported(); + } + } else { + result = SDL_SetError("Rumble failed, device disconnected"); + } + + return result; } static int VIRTUAL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) { - return SDL_Unsupported(); + int result; + + if (joystick->hwdata) { + joystick_hwdata *hwdata = joystick->hwdata; + if (hwdata->desc.RumbleTriggers) { + result = hwdata->desc.RumbleTriggers(hwdata->desc.userdata, left_rumble, right_rumble); + } else { + result = SDL_Unsupported(); + } + } else { + result = SDL_SetError("Rumble failed, device disconnected"); + } + + return result; } static Uint32 VIRTUAL_JoystickGetCapabilities(SDL_Joystick *joystick) { - return 0; + joystick_hwdata *hwdata = joystick->hwdata; + Uint32 caps = 0; + + if (hwdata) { + if (hwdata->desc.Rumble) { + caps |= SDL_JOYCAP_RUMBLE; + } + if (hwdata->desc.RumbleTriggers) { + caps |= SDL_JOYCAP_RUMBLE_TRIGGERS; + } + if (hwdata->desc.SetLED) { + caps |= SDL_JOYCAP_LED; + } + } + return caps; } static int VIRTUAL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) { - return SDL_Unsupported(); + int result; + + if (joystick->hwdata) { + joystick_hwdata *hwdata = joystick->hwdata; + if (hwdata->desc.SetLED) { + result = hwdata->desc.SetLED(hwdata->desc.userdata, red, green, blue); + } else { + result = SDL_Unsupported(); + } + } else { + result = SDL_SetError("SetLED failed, device disconnected"); + } + + return result; } static int VIRTUAL_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) { - return SDL_Unsupported(); + int result; + + if (joystick->hwdata) { + joystick_hwdata *hwdata = joystick->hwdata; + if (hwdata->desc.SendEffect) { + result = hwdata->desc.SendEffect(hwdata->desc.userdata, data, size); + } else { + result = SDL_Unsupported(); + } + } else { + result = SDL_SetError("SendEffect failed, device disconnected"); + } + + return result; } static int @@ -386,13 +576,17 @@ VIRTUAL_JoystickUpdate(SDL_Joystick *joystick) hwdata = (joystick_hwdata *)joystick->hwdata; - for (i = 0; i < hwdata->naxes; ++i) { + if (hwdata->desc.Update) { + hwdata->desc.Update(hwdata->desc.userdata); + } + + for (i = 0; i < hwdata->desc.naxes; ++i) { SDL_PrivateJoystickAxis(joystick, i, hwdata->axes[i]); } - for (i = 0; i < hwdata->nbuttons; ++i) { + for (i = 0; i < hwdata->desc.nbuttons; ++i) { SDL_PrivateJoystickButton(joystick, i, hwdata->buttons[i]); } - for (i = 0; i < hwdata->nhats; ++i) { + for (i = 0; i < hwdata->desc.nhats; ++i) { SDL_PrivateJoystickHat(joystick, i, hwdata->hats[i]); } } @@ -401,17 +595,11 @@ VIRTUAL_JoystickUpdate(SDL_Joystick *joystick) static void VIRTUAL_JoystickClose(SDL_Joystick *joystick) { - joystick_hwdata *hwdata; - - if (!joystick) { - return; + if (joystick->hwdata) { + joystick_hwdata *hwdata = joystick->hwdata; + hwdata->joystick = NULL; + joystick->hwdata = NULL; } - if (!joystick->hwdata) { - return; - } - - hwdata = (joystick_hwdata *)joystick->hwdata; - hwdata->opened = SDL_FALSE; } @@ -426,7 +614,145 @@ VIRTUAL_JoystickQuit(void) static SDL_bool VIRTUAL_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) { - return SDL_FALSE; + joystick_hwdata *hwdata = VIRTUAL_HWDataForIndex(device_index); + int current_button = 0; + int current_axis = 0; + + if (hwdata->desc.type != SDL_JOYSTICK_TYPE_GAMECONTROLLER) { + return SDL_FALSE; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_A))) { + out->a.kind = EMappingKind_Button; + out->a.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_B))) { + out->b.kind = EMappingKind_Button; + out->b.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_X))) { + out->x.kind = EMappingKind_Button; + out->x.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_Y))) { + out->y.kind = EMappingKind_Button; + out->y.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_BACK))) { + out->back.kind = EMappingKind_Button; + out->back.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_GUIDE))) { + out->guide.kind = EMappingKind_Button; + out->guide.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_START))) { + out->start.kind = EMappingKind_Button; + out->start.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_LEFTSTICK))) { + out->leftstick.kind = EMappingKind_Button; + out->leftstick.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_RIGHTSTICK))) { + out->rightstick.kind = EMappingKind_Button; + out->rightstick.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_LEFTSHOULDER))) { + out->leftshoulder.kind = EMappingKind_Button; + out->leftshoulder.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_RIGHTSHOULDER))) { + out->rightshoulder.kind = EMappingKind_Button; + out->rightshoulder.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_UP))) { + out->dpup.kind = EMappingKind_Button; + out->dpup.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_DOWN))) { + out->dpdown.kind = EMappingKind_Button; + out->dpdown.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_LEFT))) { + out->dpleft.kind = EMappingKind_Button; + out->dpleft.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_RIGHT))) { + out->dpright.kind = EMappingKind_Button; + out->dpright.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_MISC1))) { + out->misc1.kind = EMappingKind_Button; + out->misc1.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_PADDLE1))) { + out->paddle1.kind = EMappingKind_Button; + out->paddle1.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_PADDLE2))) { + out->paddle2.kind = EMappingKind_Button; + out->paddle2.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_PADDLE3))) { + out->paddle3.kind = EMappingKind_Button; + out->paddle3.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_PADDLE4))) { + out->paddle4.kind = EMappingKind_Button; + out->paddle4.target = current_button++; + } + + if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_CONTROLLER_AXIS_LEFTX))) { + out->leftx.kind = EMappingKind_Axis; + out->leftx.target = current_axis++; + } + + if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_CONTROLLER_AXIS_LEFTY))) { + out->lefty.kind = EMappingKind_Axis; + out->lefty.target = current_axis++; + } + + if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_CONTROLLER_AXIS_RIGHTX))) { + out->rightx.kind = EMappingKind_Axis; + out->rightx.target = current_axis++; + } + + if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_CONTROLLER_AXIS_RIGHTY))) { + out->righty.kind = EMappingKind_Axis; + out->righty.target = current_axis++; + } + + if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_CONTROLLER_AXIS_TRIGGERLEFT))) { + out->lefttrigger.kind = EMappingKind_Axis; + out->lefttrigger.target = current_axis++; + } + + if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_CONTROLLER_AXIS_TRIGGERRIGHT))) { + out->righttrigger.kind = EMappingKind_Axis; + out->righttrigger.target = current_axis++; + } + + return SDL_TRUE; } SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver = @@ -435,6 +761,7 @@ SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver = VIRTUAL_JoystickGetCount, VIRTUAL_JoystickDetect, VIRTUAL_JoystickGetDeviceName, + VIRTUAL_JoystickGetDevicePath, VIRTUAL_JoystickGetDevicePlayerIndex, VIRTUAL_JoystickSetDevicePlayerIndex, VIRTUAL_JoystickGetDeviceGUID, diff --git a/src/joystick/virtual/SDL_virtualjoystick_c.h b/src/joystick/virtual/SDL_virtualjoystick_c.h index b251c2d14..5e15f1dd6 100644 --- a/src/joystick/virtual/SDL_virtualjoystick_c.h +++ b/src/joystick/virtual/SDL_virtualjoystick_c.h @@ -34,24 +34,19 @@ typedef struct joystick_hwdata { SDL_JoystickType type; SDL_bool attached; - const char *name; + char *name; SDL_JoystickGUID guid; - int naxes; + SDL_VirtualJoystickDesc desc; Sint16 *axes; - int nbuttons; Uint8 *buttons; - int nhats; Uint8 *hats; SDL_JoystickID instance_id; - SDL_bool opened; + SDL_Joystick *joystick; + struct joystick_hwdata *next; } joystick_hwdata; -int SDL_JoystickAttachVirtualInner(SDL_JoystickType type, - int naxes, - int nbuttons, - int nhats); - +int SDL_JoystickAttachVirtualInner(const SDL_VirtualJoystickDesc *desc); int SDL_JoystickDetachVirtualInner(int device_index); int SDL_JoystickSetVirtualAxisInner(SDL_Joystick * joystick, int axis, Sint16 value); @@ -59,4 +54,7 @@ int SDL_JoystickSetVirtualButtonInner(SDL_Joystick * joystick, int button, Uint8 int SDL_JoystickSetVirtualHatInner(SDL_Joystick * joystick, int hat, Uint8 value); #endif /* SDL_JOYSTICK_VIRTUAL */ + #endif /* SDL_VIRTUALJOYSTICK_C_H */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/joystick/vita/SDL_sysjoystick.c b/src/joystick/vita/SDL_sysjoystick.c index aa52cd77f..b5c7a2778 100644 --- a/src/joystick/vita/SDL_sysjoystick.c +++ b/src/joystick/vita/SDL_sysjoystick.c @@ -179,7 +179,6 @@ SDL_JoystickID VITA_JoystickGetDeviceInstanceID(int device_index) return device_index; } -/* Function to get the device-dependent name of a joystick */ const char *VITA_JoystickGetDeviceName(int index) { if (index == 0) @@ -195,7 +194,12 @@ const char *VITA_JoystickGetDeviceName(int index) return "PSVita Controller"; SDL_SetError("No joystick available with that index"); - return(NULL); + return NULL; +} + +const char *VITA_JoystickGetDevicePath(int index) +{ + return NULL; } static int @@ -400,6 +404,7 @@ SDL_JoystickDriver SDL_VITA_JoystickDriver = VITA_JoystickGetCount, VITA_JoystickDetect, VITA_JoystickGetDeviceName, + VITA_JoystickGetDevicePath, VITA_JoystickGetDevicePlayerIndex, VITA_JoystickSetDevicePlayerIndex, VITA_JoystickGetDeviceGUID, diff --git a/src/joystick/windows/SDL_dinputjoystick.c b/src/joystick/windows/SDL_dinputjoystick.c index c2f53a93f..7b4c23ee0 100644 --- a/src/joystick/windows/SDL_dinputjoystick.c +++ b/src/joystick/windows/SDL_dinputjoystick.c @@ -456,7 +456,7 @@ EnumJoystickDetectCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID pContext) pNewJoystick = *(JoyStick_DeviceData**)pContext; while (pNewJoystick) { /* update GUIDs of joysticks with matching paths, in case they're not open yet */ - if (SDL_strcmp(pNewJoystick->hidPath, hidPath) == 0) { + if (SDL_strcmp(pNewJoystick->path, hidPath) == 0) { /* if we are replacing the front of the list then update it */ if (pNewJoystick == *(JoyStick_DeviceData**)pContext) { *(JoyStick_DeviceData**)pContext = pNewJoystick->pNext; @@ -483,7 +483,7 @@ EnumJoystickDetectCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID pContext) CHECK(pNewJoystick); SDL_zerop(pNewJoystick); - SDL_strlcpy(pNewJoystick->hidPath, hidPath, SDL_arraysize(pNewJoystick->hidPath)); + SDL_strlcpy(pNewJoystick->path, hidPath, SDL_arraysize(pNewJoystick->path)); SDL_memcpy(&pNewJoystick->dxdevice, pDeviceInstance, sizeof(DIDEVICEINSTANCE)); SDL_memset(pNewJoystick->guid.data, 0, sizeof(pNewJoystick->guid.data)); @@ -683,7 +683,7 @@ EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE pDeviceObject, LPVOID pContext) /* Sort using the data offset into the DInput struct. * This gives a reasonable ordering for the inputs. */ -static int +static int SDLCALL SortDevFunc(const void *a, const void *b) { const input_t *inputA = (const input_t*)a; diff --git a/src/joystick/windows/SDL_rawinputjoystick.c b/src/joystick/windows/SDL_rawinputjoystick.c index df40232df..ca9bd7d37 100644 --- a/src/joystick/windows/SDL_rawinputjoystick.c +++ b/src/joystick/windows/SDL_rawinputjoystick.c @@ -105,6 +105,7 @@ typedef struct _SDL_RAWINPUT_Device { SDL_atomic_t refcount; char *name; + char *path; Uint16 vendor_id; Uint16 product_id; Uint16 version; @@ -689,10 +690,9 @@ RAWINPUT_ReleaseDevice(SDL_RAWINPUT_Device *device) #endif /* SDL_JOYSTICK_RAWINPUT_XINPUT */ if (SDL_AtomicDecRef(&device->refcount)) { - if (device->preparsed_data) { - SDL_HidD_FreePreparsedData(device->preparsed_data); - } + SDL_free(device->preparsed_data); SDL_free(device->name); + SDL_free(device->path); SDL_free(device); } } @@ -716,9 +716,8 @@ RAWINPUT_AddDevice(HANDLE hDevice) SDL_RAWINPUT_Device *device = NULL; SDL_RAWINPUT_Device *curr, *last; RID_DEVICE_INFO rdi; - UINT rdi_size = sizeof(rdi); + UINT size; char dev_name[MAX_PATH]; - UINT name_size = SDL_arraysize(dev_name); HANDLE hFile = INVALID_HANDLE_VALUE; /* Make sure we're not trying to add the same device twice */ @@ -727,11 +726,13 @@ RAWINPUT_AddDevice(HANDLE hDevice) } /* Figure out what kind of device it is */ - CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_DEVICEINFO, &rdi, &rdi_size) != (UINT)-1); + size = sizeof(rdi); + CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_DEVICEINFO, &rdi, &size) != (UINT)-1); CHECK(rdi.dwType == RIM_TYPEHID); /* Get the device "name" (HID Path) */ - CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_DEVICENAME, dev_name, &name_size) != (UINT)-1); + size = SDL_arraysize(dev_name); + CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_DEVICENAME, dev_name, &size) != (UINT)-1); /* Only take XInput-capable devices */ CHECK(SDL_strstr(dev_name, "IG_") != NULL); #ifdef SDL_JOYSTICK_HIDAPI @@ -747,6 +748,12 @@ RAWINPUT_AddDevice(HANDLE hDevice) device->is_xinput = SDL_TRUE; device->is_xboxone = GuessControllerType(device->vendor_id, device->product_id) == k_eControllerType_XBoxOneController; + /* Get HID Top-Level Collection Preparsed Data */ + size = 0; + CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_PREPARSEDDATA, NULL, &size) != (UINT)-1); + CHECK(device->preparsed_data = (PHIDP_PREPARSED_DATA)SDL_calloc(size, sizeof(BYTE))); + CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_PREPARSEDDATA, device->preparsed_data, &size) != (UINT)-1); + { const Uint16 vendor = device->vendor_id; const Uint16 product = device->product_id; @@ -791,8 +798,7 @@ RAWINPUT_AddDevice(HANDLE hDevice) SDL_free(product_string); } } - - CHECK(SDL_HidD_GetPreparsedData(hFile, &device->preparsed_data)); + device->path = SDL_strdup(dev_name); CloseHandle(hFile); hFile = INVALID_HANDLE_VALUE; @@ -825,8 +831,12 @@ err: CloseHandle(hFile); } if (device) { - if (device->name) + if (device->name) { SDL_free(device->name); + } + if (device->path) { + SDL_free(device->path); + } SDL_free(device); } #undef CHECK @@ -1029,6 +1039,12 @@ RAWINPUT_JoystickGetDeviceName(int device_index) return RAWINPUT_GetDeviceByIndex(device_index)->name; } +static const char * +RAWINPUT_JoystickGetDevicePath(int device_index) +{ + return RAWINPUT_GetDeviceByIndex(device_index)->path; +} + static int RAWINPUT_JoystickGetDevicePlayerIndex(int device_index) { @@ -1053,7 +1069,7 @@ RAWINPUT_JoystickGetDeviceInstanceID(int device_index) return RAWINPUT_GetDeviceByIndex(device_index)->joystick_id; } -static int +static int SDLCALL RAWINPUT_SortValueCaps(const void *A, const void *B) { HIDP_VALUE_CAPS *capsA = (HIDP_VALUE_CAPS *)A; @@ -1253,7 +1269,7 @@ RAWINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index) } } - SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_UNKNOWN); + joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN; return 0; } @@ -1263,8 +1279,8 @@ RAWINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uin { #if defined(SDL_JOYSTICK_RAWINPUT_WGI) || defined(SDL_JOYSTICK_RAWINPUT_XINPUT) RAWINPUT_DeviceContext *ctx = joystick->hwdata; - SDL_bool rumbled = SDL_FALSE; #endif + SDL_bool rumbled = SDL_FALSE; #ifdef SDL_JOYSTICK_RAWINPUT_WGI if (!rumbled && ctx->wgi_correlated) { @@ -1312,7 +1328,7 @@ RAWINPUT_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint { #if defined(SDL_JOYSTICK_RAWINPUT_WGI) RAWINPUT_DeviceContext *ctx = joystick->hwdata; - + if (ctx->wgi_correlated) { WindowsGamingInputGamepadState *gamepad_state = ctx->wgi_slot; HRESULT hr; @@ -1570,17 +1586,25 @@ RAWINPUT_UpdateOtherAPIs(SDL_Joystick *joystick) int guide_button = joystick->nbuttons - 1; int left_trigger = joystick->naxes - 2; int right_trigger = joystick->naxes - 1; +#ifdef SDL_JOYSTICK_RAWINPUT_WGI + SDL_bool xinput_correlated; +#endif RAWINPUT_FillMatchState(&match_state_xinput, ctx->match_state); #ifdef SDL_JOYSTICK_RAWINPUT_WGI + #ifdef SDL_JOYSTICK_RAWINPUT_XINPUT + xinput_correlated = ctx->xinput_correlated; + #else + xinput_correlated = SDL_FALSE; + #endif /* Parallel logic to WINDOWS_XINPUT below */ RAWINPUT_UpdateWindowsGamingInput(); if (ctx->wgi_correlated && !joystick->low_frequency_rumble && !joystick->high_frequency_rumble && !joystick->left_trigger_rumble && !joystick->right_trigger_rumble) { /* We have been previously correlated, ensure we are still matching, see comments in XINPUT section */ - if (RAWINPUT_WindowsGamingInputSlotMatches(&match_state_xinput, ctx->wgi_slot, ctx->xinput_correlated)) { + if (RAWINPUT_WindowsGamingInputSlotMatches(&match_state_xinput, ctx->wgi_slot, xinput_correlated)) { ctx->wgi_uncorrelate_count = 0; } else { ++ctx->wgi_uncorrelate_count; @@ -1609,7 +1633,7 @@ RAWINPUT_UpdateOtherAPIs(SDL_Joystick *joystick) if (RAWINPUT_MissingWindowsGamingInputSlot()) { Uint8 correlation_id; WindowsGamingInputGamepadState *slot_idx = NULL; - if (RAWINPUT_GuessWindowsGamingInputSlot(&match_state_xinput, &correlation_id, &slot_idx, ctx->xinput_correlated)) { + if (RAWINPUT_GuessWindowsGamingInputSlot(&match_state_xinput, &correlation_id, &slot_idx, xinput_correlated)) { /* we match exactly one WindowsGamingInput device */ /* Probably can do without wgi_correlation_count, just check and clear wgi_slot to NULL, unless we need even more frames to be sure. */ @@ -1911,7 +1935,7 @@ RAWINPUT_UnregisterNotifications() return; } } - + LRESULT CALLBACK RAWINPUT_WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { @@ -2006,6 +2030,7 @@ SDL_JoystickDriver SDL_RAWINPUT_JoystickDriver = RAWINPUT_JoystickGetCount, RAWINPUT_JoystickDetect, RAWINPUT_JoystickGetDeviceName, + RAWINPUT_JoystickGetDevicePath, RAWINPUT_JoystickGetDevicePlayerIndex, RAWINPUT_JoystickSetDevicePlayerIndex, RAWINPUT_JoystickGetDeviceGUID, diff --git a/src/joystick/windows/SDL_windows_gaming_input.c b/src/joystick/windows/SDL_windows_gaming_input.c index 6c5ec5528..8b552bb7d 100644 --- a/src/joystick/windows/SDL_windows_gaming_input.c +++ b/src/joystick/windows/SDL_windows_gaming_input.c @@ -586,6 +586,12 @@ WGI_JoystickGetDeviceName(int device_index) return wgi.controllers[device_index].name; } +static const char * +WGI_JoystickGetDevicePath(int device_index) +{ + return NULL; +} + static int WGI_JoystickGetDevicePlayerIndex(int device_index) { @@ -893,6 +899,7 @@ SDL_JoystickDriver SDL_WGI_JoystickDriver = WGI_JoystickGetCount, WGI_JoystickDetect, WGI_JoystickGetDeviceName, + WGI_JoystickGetDevicePath, WGI_JoystickGetDevicePlayerIndex, WGI_JoystickSetDevicePlayerIndex, WGI_JoystickGetDeviceGUID, diff --git a/src/joystick/windows/SDL_windowsjoystick.c b/src/joystick/windows/SDL_windowsjoystick.c index 7dae16d9f..463afd7e5 100644 --- a/src/joystick/windows/SDL_windowsjoystick.c +++ b/src/joystick/windows/SDL_windowsjoystick.c @@ -330,7 +330,7 @@ SDL_WaitForDeviceNotification(SDL_DeviceNotificationData *data, SDL_mutex *mutex static SDL_DeviceNotificationData s_notification_data; /* Function/thread to scan the system for joysticks. */ -static int +static int SDLCALL SDL_JoystickThread(void *_data) { #if SDL_JOYSTICK_XINPUT @@ -555,7 +555,6 @@ WINDOWS_JoystickDetect(void) } } -/* Function to get the device-dependent name of a joystick */ static const char * WINDOWS_JoystickGetDeviceName(int device_index) { @@ -568,6 +567,18 @@ WINDOWS_JoystickGetDeviceName(int device_index) return device->joystickname; } +static const char * +WINDOWS_JoystickGetDevicePath(int device_index) +{ + JoyStick_DeviceData *device = SYS_Joystick; + int index; + + for (index = device_index; index > 0; index--) + device = device->pNext; + + return device->path; +} + static int WINDOWS_JoystickGetDevicePlayerIndex(int device_index) { @@ -755,6 +766,7 @@ SDL_JoystickDriver SDL_WINDOWS_JoystickDriver = WINDOWS_JoystickGetCount, WINDOWS_JoystickDetect, WINDOWS_JoystickGetDeviceName, + WINDOWS_JoystickGetDevicePath, WINDOWS_JoystickGetDevicePlayerIndex, WINDOWS_JoystickSetDevicePlayerIndex, WINDOWS_JoystickGetDeviceGUID, diff --git a/src/joystick/windows/SDL_windowsjoystick_c.h b/src/joystick/windows/SDL_windowsjoystick_c.h index 1b9625385..d7e09abde 100644 --- a/src/joystick/windows/SDL_windowsjoystick_c.h +++ b/src/joystick/windows/SDL_windowsjoystick_c.h @@ -37,7 +37,7 @@ typedef struct JoyStick_DeviceData BYTE SubType; Uint8 XInputUserId; DIDEVICEINSTANCE dxdevice; - char hidPath[MAX_PATH]; + char path[MAX_PATH]; struct JoyStick_DeviceData *pNext; } JoyStick_DeviceData; diff --git a/src/joystick/windows/SDL_xinputjoystick.c b/src/joystick/windows/SDL_xinputjoystick.c index f3ab8a0b2..439957399 100644 --- a/src/joystick/windows/SDL_xinputjoystick.c +++ b/src/joystick/windows/SDL_xinputjoystick.c @@ -297,6 +297,7 @@ AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext) SDL_free(pNewJoystick); return; /* better luck next time? */ } + SDL_snprintf(pNewJoystick->path, sizeof(pNewJoystick->path), "XInput#%d", userid); if (SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid)) { SDL_free(pNewJoystick); diff --git a/src/libm/math_private.h b/src/libm/math_private.h index 4a30a521a..2e4bb1402 100644 --- a/src/libm/math_private.h +++ b/src/libm/math_private.h @@ -66,9 +66,10 @@ typedef unsigned int u_int32_t; * Math on arm is special: * For FPA, float words are always big-endian. * For VFP, floats words follow the memory system mode. + * For Maverick, float words are always little-endian. */ -#if (SDL_BYTEORDER == SDL_BIG_ENDIAN) +#if (SDL_FLOATWORDORDER == SDL_BIG_ENDIAN) typedef union { diff --git a/src/main/ngage/SDL_ngage_main.cpp b/src/main/ngage/SDL_ngage_main.cpp new file mode 100644 index 000000000..6dbf2f141 --- /dev/null +++ b/src/main/ngage/SDL_ngage_main.cpp @@ -0,0 +1,82 @@ +/* + SDL_ngage_main.c, originally for SDL 1.2 by Hannu Viitala +*/ +#include "../../SDL_internal.h" + +/* Include the SDL main definition header */ +#include "SDL_main.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "SDL_error.h" + +extern "C" int main(int argc, char *argv[]); + +TInt E32Main() +{ + /* Get the clean-up stack */ + CTrapCleanup* cleanup = CTrapCleanup::New(); + + /* Arrange for multi-threaded operation */ + SpawnPosixServerThread(); + + /* Get args and environment */ + int argc = 0; + char** argv = 0; + char** envp = 0; + + __crt0(argc,argv,envp); + + /* Start the application! */ + + /* Create stdlib */ + _REENT; + + /* Set process and thread priority and name */ + + RThread currentThread; + RProcess thisProcess; + TParse exeName; + exeName.Set(thisProcess.FileName(), NULL, NULL); + currentThread.Rename(exeName.Name()); + currentThread.SetProcessPriority(EPriorityLow); + currentThread.SetPriority(EPriorityMuchLess); + + /* Increase heap size */ + RHeap* newHeap = NULL; + RHeap* oldHeap = NULL; + TInt heapSize = 7500000; + int ret; + + newHeap = User::ChunkHeap(NULL, heapSize, heapSize, KMinHeapGrowBy); + + if (NULL == newHeap) + { + ret = 3; + goto cleanup; + } + else + { + oldHeap = User::SwitchHeap(newHeap); + /* Call stdlib main */ + SDL_SetMainReady(); + ret = SDL_main(argc, argv); + } + +cleanup: + _cleanup(); + + CloseSTDLIB(); + delete cleanup; + return ret; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/main/uikit/SDL_uikit_main.c b/src/main/uikit/SDL_uikit_main.c index 702f67391..62cfffd5c 100644 --- a/src/main/uikit/SDL_uikit_main.c +++ b/src/main/uikit/SDL_uikit_main.c @@ -1,7 +1,6 @@ /* SDL_uikit_main.c, placed in the public domain by Sam Lantinga 3/18/2019 */ -#include "../../SDL_internal.h" /* Include the SDL main definition header */ #include "SDL_main.h" diff --git a/src/main/windows/version.rc b/src/main/windows/version.rc index f106c5f48..66ab6204e 100644 --- a/src/main/windows/version.rc +++ b/src/main/windows/version.rc @@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,0,22,0 - PRODUCTVERSION 2,0,22,0 + FILEVERSION 2,23,0,0 + PRODUCTVERSION 2,23,0,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -23,12 +23,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "2, 0, 22, 0\0" + VALUE "FileVersion", "2, 23, 0, 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, 22, 0\0" + VALUE "ProductVersion", "2, 23, 0, 0\0" END END BLOCK "VarFileInfo" diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 58cda3d60..d94b0a988 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -2670,11 +2670,16 @@ static int RenderDrawPointsWithRects(SDL_Renderer * renderer, const SDL_Point * points, const int count) { - int retval = -1; + int retval; SDL_bool isstack; - SDL_FRect *frects = SDL_small_alloc(SDL_FRect, count, &isstack); + SDL_FRect *frects; int i; + if (count < 1) { + return 0; + } + + frects = SDL_small_alloc(SDL_FRect, count, &isstack); if (!frects) { return SDL_OutOfMemory(); } @@ -2686,9 +2691,7 @@ RenderDrawPointsWithRects(SDL_Renderer * renderer, frects[i].h = renderer->scale.y; } - if (count) { - retval = QueueCmdFillRects(renderer, frects, count); - } + retval = QueueCmdFillRects(renderer, frects, count); SDL_small_free(frects, isstack); @@ -2743,11 +2746,16 @@ static int RenderDrawPointsWithRectsF(SDL_Renderer * renderer, const SDL_FPoint * fpoints, const int count) { - int retval = -1; + int retval; SDL_bool isstack; - SDL_FRect *frects = SDL_small_alloc(SDL_FRect, count, &isstack); + SDL_FRect *frects; int i; + if (count < 1) { + return 0; + } + + frects = SDL_small_alloc(SDL_FRect, count, &isstack); if (!frects) { return SDL_OutOfMemory(); } @@ -2759,9 +2767,7 @@ RenderDrawPointsWithRectsF(SDL_Renderer * renderer, frects[i].h = renderer->scale.y; } - if (count) { - retval = QueueCmdFillRects(renderer, frects, count); - } + retval = QueueCmdFillRects(renderer, frects, count); SDL_small_free(frects, isstack); diff --git a/src/render/direct3d/SDL_render_d3d.c b/src/render/direct3d/SDL_render_d3d.c index 477f4e975..97047f4bf 100644 --- a/src/render/direct3d/SDL_render_d3d.c +++ b/src/render/direct3d/SDL_render_d3d.c @@ -41,6 +41,13 @@ #include "SDL_shaders_d3d.h" +#ifdef __WATCOMC__ +/* FIXME: Remove this once https://github.com/open-watcom/open-watcom-v2/pull/868 is merged */ +#define D3DBLENDOP_REVSUBTRACT 3 +/* FIXME: Remove this once https://github.com/open-watcom/open-watcom-v2/pull/869 is merged */ +#define D3DERR_UNSUPPORTEDCOLOROPERATION MAKE_D3DHRESULT( 2073 ) +#endif + typedef struct { SDL_Rect viewport; @@ -1079,7 +1086,13 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd) if (data->drawstate.viewport_dirty) { const SDL_Rect *viewport = &data->drawstate.viewport; - const D3DVIEWPORT9 d3dviewport = { viewport->x, viewport->y, viewport->w, viewport->h, 0.0f, 1.0f }; + D3DVIEWPORT9 d3dviewport; + d3dviewport.X = viewport->x; + d3dviewport.Y = viewport->y; + d3dviewport.Width = viewport->w; + d3dviewport.Height = viewport->h; + d3dviewport.MinZ = 0.0f; + d3dviewport.MaxZ = 1.0f; IDirect3DDevice9_SetViewport(data->device, &d3dviewport); /* Set an orthographic projection matrix */ @@ -1106,7 +1119,11 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd) if (data->drawstate.cliprect_dirty) { const SDL_Rect *viewport = &data->drawstate.viewport; const SDL_Rect *rect = &data->drawstate.cliprect; - const RECT d3drect = { viewport->x + rect->x, viewport->y + rect->y, viewport->x + rect->x + rect->w, viewport->y + rect->y + rect->h }; + RECT d3drect; + d3drect.left = viewport->x + rect->x; + d3drect.top = viewport->y + rect->y; + d3drect.right = viewport->x + rect->x + rect->w; + d3drect.bottom = viewport->y + rect->y + rect->h; IDirect3DDevice9_SetScissorRect(data->device, &d3drect); data->drawstate.cliprect_dirty = SDL_FALSE; } @@ -1221,7 +1238,9 @@ D3D_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti IDirect3DDevice9_Clear(data->device, 0, NULL, D3DCLEAR_TARGET, color, 0.0f, 0); } else { /* Clear is defined to clear the entire render target */ - const D3DVIEWPORT9 wholeviewport = { 0, 0, backw, backh, 0.0f, 1.0f }; + D3DVIEWPORT9 wholeviewport = { 0, 0, 0, 0, 0.0f, 1.0f }; + wholeviewport.Width = backw; + wholeviewport.Height = backh; IDirect3DDevice9_SetViewport(data->device, &wholeviewport); data->drawstate.viewport_dirty = SDL_TRUE; /* we still need to (re)set orthographic projection, so always mark it dirty. */ IDirect3DDevice9_Clear(data->device, 0, NULL, D3DCLEAR_TARGET, color, 0.0f, 0); diff --git a/src/render/metal/SDL_render_metal.m b/src/render/metal/SDL_render_metal.m index 329e5b3a0..6ade20c12 100644 --- a/src/render/metal/SDL_render_metal.m +++ b/src/render/metal/SDL_render_metal.m @@ -142,24 +142,6 @@ typedef struct METAL_ShaderPipelines @end @implementation METAL_RenderData -#if !__has_feature(objc_arc) -- (void)dealloc -{ - [_mtldevice release]; - [_mtlcmdqueue release]; - [_mtlcmdbuffer release]; - [_mtlcmdencoder release]; - [_mtllibrary release]; - [_mtlbackbuffer release]; - [_mtlsamplernearest release]; - [_mtlsamplerlinear release]; - [_mtlbufconstants release]; - [_mtlbufquadindices release]; - [_mtllayer release]; - [_mtlpassdesc release]; - [super dealloc]; -} -#endif @end @interface METAL_TextureData : NSObject @@ -178,16 +160,6 @@ typedef struct METAL_ShaderPipelines @end @implementation METAL_TextureData -#if !__has_feature(objc_arc) -- (void)dealloc -{ - [_mtltexture release]; - [_mtltexture_uv release]; - [_mtlsampler release]; - [_lockedbuffer release]; - [super dealloc]; -} -#endif @end static int @@ -342,13 +314,6 @@ MakePipelineState(METAL_RenderData *data, METAL_PipelineCache *cache, METAL_PipelineState *states = SDL_realloc(cache->states, (cache->count + 1) * sizeof(pipeline)); -#if !__has_feature(objc_arc) - [mtlpipedesc release]; // !!! FIXME: can these be reused for each creation, or does the pipeline obtain it? - [mtlvertfn release]; - [mtlfragfn release]; - [state release]; -#endif - if (states) { states[cache->count++] = pipeline; cache->states = states; @@ -632,9 +597,6 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) if (yuv || nv12) { mtltexture_uv = [data.mtldevice newTextureWithDescriptor:mtltexdesc]; if (mtltexture_uv == nil) { -#if !__has_feature(objc_arc) - [mtltexture release]; -#endif return SDL_SetError("Texture allocation failed"); } } @@ -677,12 +639,6 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) #endif texture->driverdata = (void*)CFBridgingRetain(texturedata); -#if !__has_feature(objc_arc) - [texturedata release]; - [mtltexture release]; - [mtltexture_uv release]; -#endif - return 0; }} @@ -742,10 +698,6 @@ METAL_UpdateTextureInternal(SDL_Renderer * renderer, METAL_TextureData *textured return SDL_OutOfMemory(); } -#if !__has_feature(objc_arc) - [stagingtex autorelease]; -#endif - METAL_UploadTextureData(stagingtex, stagingrect, 0, pixels, pitch); if (data.mtlcmdencoder != nil) { @@ -917,11 +869,6 @@ METAL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, texturedata.lockedbuffer = lockedbuffer; *pixels = [lockedbuffer contents]; - /* METAL_TextureData.lockedbuffer retains. */ -#if !__has_feature(objc_arc) - [lockedbuffer release]; -#endif - return 0; }} @@ -1209,13 +1156,8 @@ METAL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture typedef struct { - #if __has_feature(objc_arc) __unsafe_unretained id pipeline; __unsafe_unretained id vertex_buffer; - #else - id pipeline; - id vertex_buffer; - #endif size_t constants_offset; SDL_Texture *texture; SDL_bool cliprect_dirty; @@ -1365,9 +1307,6 @@ METAL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver * TODO: this buffer is also used for constants. Is performance still * good for those, or should we have a managed buffer for them? */ mtlbufvertex = [data.mtldevice newBufferWithLength:vertsize options:MTLResourceStorageModeShared]; - #if !__has_feature(objc_arc) - [mtlbufvertex autorelease]; - #endif mtlbufvertex.label = @"SDL vertex data"; SDL_memcpy([mtlbufvertex contents], vertices, vertsize); @@ -1711,9 +1650,6 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags) } if (view == NULL) { -#if !__has_feature(objc_arc) - [mtldevice release]; -#endif SDL_free(renderer); if (changed_window) { SDL_RecreateWindow(window, window_flags); @@ -1725,9 +1661,6 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags) data = [[METAL_RenderData alloc] init]; if (data == nil) { -#if !__has_feature(objc_arc) - [mtldevice release]; -#endif /* Release the metal view instead of destroying it, in case we want to use it later (recreating the renderer) */ @@ -1746,7 +1679,7 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags) data.mtlview = view; #ifdef __MACOSX__ - layer = (CAMetalLayer *)[(NSView *)view layer]; + layer = (CAMetalLayer *)[(__bridge NSView *)view layer]; #else layer = (CAMetalLayer *)[(__bridge UIView *)view layer]; #endif @@ -1771,9 +1704,6 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags) id mtllibrary = [data.mtldevice newLibraryWithData:mtllibdata error:&err]; data.mtllibrary = mtllibrary; SDL_assert(err == nil); -#if !__has_feature(objc_arc) - dispatch_release(mtllibdata); -#endif data.mtllibrary.label = @"SDL Metal renderer shader library"; /* Do some shader pipeline state loading up-front rather than on demand. */ @@ -1831,9 +1761,6 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags) }; id mtlbufconstantstaging = [data.mtldevice newBufferWithLength:CONSTANTS_LENGTH options:MTLResourceStorageModeShared]; - #if !__has_feature(objc_arc) - [mtlbufconstantstaging autorelease]; - #endif char *constantdata = [mtlbufconstantstaging contents]; SDL_memcpy(constantdata + CONSTANTS_OFFSET_IDENTITY, identitytransform, sizeof(identitytransform)); @@ -1845,9 +1772,6 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags) int quadcount = UINT16_MAX / 4; size_t indicessize = sizeof(UInt16) * quadcount * 6; id mtlbufquadindicesstaging = [data.mtldevice newBufferWithLength:indicessize options:MTLResourceStorageModeShared]; -#if !__has_feature(objc_arc) - [mtlbufquadindicesstaging autorelease]; -#endif /* Quads in the following vertex order (matches the FillRects vertices): * 1---3 @@ -1965,18 +1889,6 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->info.max_texture_width = maxtexsize; renderer->info.max_texture_height = maxtexsize; -#if !__has_feature(objc_arc) - [mtlcmdqueue release]; - [mtllibrary release]; - [samplerdesc release]; - [mtlsamplernearest release]; - [mtlsamplerlinear release]; - [mtlbufconstants release]; - [mtlbufquadindices release]; - [data release]; - [mtldevice release]; -#endif - return renderer; }} diff --git a/src/render/software/SDL_rotate.c b/src/render/software/SDL_rotate.c index 6a9efac9c..d5ffc147a 100644 --- a/src/render/software/SDL_rotate.c +++ b/src/render/software/SDL_rotate.c @@ -61,11 +61,6 @@ typedef struct tColorY { Uint8 y; } tColorY; -/* ! -\brief Returns maximum of two numbers a and b. -*/ -#define MAX(a,b) (((a) > (b)) ? (a) : (b)) - /* ! \brief Number of guard rows added to destination surfaces. diff --git a/src/render/software/SDL_rotate.h b/src/render/software/SDL_rotate.h index 171baa5dd..8d7ec9d28 100644 --- a/src/render/software/SDL_rotate.h +++ b/src/render/software/SDL_rotate.h @@ -22,10 +22,6 @@ #ifndef SDL_rotate_h_ #define SDL_rotate_h_ -#ifndef MIN -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) -#endif - extern SDL_Surface *SDLgfx_rotateSurface(SDL_Surface * src, double angle, int smooth, int flipx, int flipy, const SDL_Rect *rect_dest, double cangle, double sangle, const SDL_FPoint *center); extern void SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, const SDL_FPoint *center, diff --git a/src/stdlib/SDL_iconv.c b/src/stdlib/SDL_iconv.c index 3f5c82745..f3a4cbbee 100644 --- a/src/stdlib/SDL_iconv.c +++ b/src/stdlib/SDL_iconv.c @@ -126,7 +126,7 @@ static struct const char *name; int format; } encodings[] = { -/* *INDENT-OFF* */ +/* *INDENT-OFF* */ /* clang-format off */ { "ASCII", ENCODING_ASCII }, { "US-ASCII", ENCODING_ASCII }, { "8859-1", ENCODING_LATIN1 }, @@ -160,7 +160,7 @@ static struct { "UCS-4LE", ENCODING_UCS4LE }, { "UCS-4BE", ENCODING_UCS4BE }, { "UCS-4-INTERNAL", ENCODING_UCS4NATIVE }, -/* *INDENT-ON* */ +/* *INDENT-ON* */ /* clang-format on */ }; static const char * diff --git a/src/stdlib/SDL_malloc.c b/src/stdlib/SDL_malloc.c index 7dc5a4211..0a51dddce 100644 --- a/src/stdlib/SDL_malloc.c +++ b/src/stdlib/SDL_malloc.c @@ -733,7 +733,7 @@ extern "C" maximum supported value of n differs across systems, but is in all cases less than the maximum representable value of a size_t. */ - void *dlmalloc(size_t); + void * SDLCALL dlmalloc(size_t); /* free(void* p) @@ -742,14 +742,14 @@ extern "C" It has no effect if p is null. If p was not malloced or already freed, free(p) will by default cause the current program to abort. */ - void dlfree(void *); + void SDLCALL dlfree(void *); /* calloc(size_t n_elements, size_t element_size); Returns a pointer to n_elements * element_size bytes, with all locations set to zero. */ - void *dlcalloc(size_t, size_t); + void * SDLCALL dlcalloc(size_t, size_t); /* realloc(void* p, size_t n) @@ -774,7 +774,7 @@ extern "C" to be used as an argument to realloc is not supported. */ - void *dlrealloc(void *, size_t); + void * SDLCALL dlrealloc(void *, size_t); /* memalign(size_t alignment, size_t n); diff --git a/src/stdlib/SDL_qsort.c b/src/stdlib/SDL_qsort.c index b175f444e..26e97c908 100644 --- a/src/stdlib/SDL_qsort.c +++ b/src/stdlib/SDL_qsort.c @@ -534,5 +534,38 @@ extern void qsortG(void *base, size_t nmemb, size_t size, #endif /* HAVE_QSORT */ +void * +SDL_bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compare)(const void *, const void *)) +{ +#if defined(HAVE_BSEARCH) + return bsearch(key, base, nmemb, size, compare); +#else +/* SDL's replacement: Taken from the Public Domain C Library (PDCLib): + Permission is granted to use, modify, and / or redistribute at will. +*/ + const void *pivot; + size_t corr; + int rc; + + while (nmemb) { + /* algorithm needs -1 correction if remaining elements are an even number. */ + corr = nmemb % 2; + nmemb /= 2; + pivot = (const char *)base + (nmemb * size); + rc = compare(key, pivot); + + if (rc > 0) { + base = (const char *)pivot + size; + /* applying correction */ + nmemb -= (1 - corr); + } else if (rc == 0) { + return (void *)pivot; + } + } + + return NULL; +#endif /* HAVE_BSEARCH */ +} + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/stdlib/SDL_stdlib.c b/src/stdlib/SDL_stdlib.c index 9d785aad5..62cbef884 100644 --- a/src/stdlib/SDL_stdlib.c +++ b/src/stdlib/SDL_stdlib.c @@ -549,8 +549,9 @@ int SDL_isblank(int x) { return ((x) == ' ') || ((x) == '\t'); } __declspec(selectany) int _fltused = 1; #endif -/* The optimizer on Visual Studio 2005 and later generates memcpy() and memset() calls */ -#if _MSC_VER >= 1400 +/* The optimizer on Visual Studio 2005 and later generates memcpy() and memset() calls. + Always provide it for the SDL2 DLL, but skip it when building static lib w/ static runtime. */ +#if (_MSC_VER >= 1400) && (!defined(_MT) || defined(DLL_EXPORT)) extern void *memcpy(void* dst, const void* src, size_t len); #pragma intrinsic(memcpy) @@ -570,7 +571,7 @@ memset(void *dst, int c, size_t len) { return SDL_memset(dst, c, len); } -#endif /* _MSC_VER >= 1400 */ +#endif /* (_MSC_VER >= 1400) && (!defined(_MT) || defined(DLL_EXPORT)) */ #ifdef _M_IX86 diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c index 133193072..3125e8390 100644 --- a/src/stdlib/SDL_string.c +++ b/src/stdlib/SDL_string.c @@ -27,14 +27,7 @@ /* This file contains portable string manipulation functions for SDL */ #include "SDL_stdinc.h" - -#if defined(_MSC_VER) && _MSC_VER <= 1800 -/* Visual Studio 2013 tries to link with _vacopy in the C runtime. Newer versions do an inline assignment */ -#undef va_copy -#define va_copy(dst, src) dst = src -#elif defined(__GNUC__) && (__GNUC__ < 3) -#define va_copy(to, from) __va_copy(to, from) -#endif +#include "SDL_vacopy.h" #if !defined(HAVE_VSSCANF) || !defined(HAVE_STRTOL) || !defined(HAVE_STRTOUL) || !defined(HAVE_STRTOD) || !defined(HAVE_STRTOLL) || !defined(HAVE_STRTOULL) #define SDL_isupperhex(X) (((X) >= 'A') && ((X) <= 'F')) diff --git a/src/stdlib/SDL_vacopy.h b/src/stdlib/SDL_vacopy.h new file mode 100644 index 000000000..ab6004695 --- /dev/null +++ b/src/stdlib/SDL_vacopy.h @@ -0,0 +1,36 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + 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. +*/ + +/* Do our best to make sure va_copy is working */ +#if defined(__NGAGE__) +#undef va_copy +#define va_copy(dst, src) dst = src + +#elif defined(_MSC_VER) && _MSC_VER <= 1800 +/* Visual Studio 2013 tries to link with _vacopy in the C runtime. Newer versions do an inline assignment */ +#undef va_copy +#define va_copy(dst, src) dst = src + +#elif defined(__GNUC__) && (__GNUC__ < 3) +#define va_copy(dst, src) __va_copy(dst, src) +#endif + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/test/SDL_test_harness.c b/src/test/SDL_test_harness.c index 8f10f3e5c..3a1f432b0 100644 --- a/src/test/SDL_test_harness.c +++ b/src/test/SDL_test_harness.c @@ -169,7 +169,7 @@ SDLTest_GenerateExecKey(const char *runSeed, const char *suiteName, const char * * \return Timer id or -1 on failure. */ static SDL_TimerID -SDLTest_SetTestTimeout(int timeout, void (*callback)(void)) +SDLTest_SetTestTimeout(int timeout, void (SDLCALL *callback)(void)) { Uint32 timeoutInMilliseconds; SDL_TimerID timerID; @@ -209,7 +209,7 @@ SDLTest_SetTestTimeout(int timeout, void (*callback)(void)) #if defined(__WATCOMC__) #pragma aux SDLTest_BailOut aborts; #endif -static SDL_NORETURN void +static SDL_NORETURN void SDLCALL SDLTest_BailOut(void) { SDLTest_LogError("TestCaseTimeout timer expired. Aborting test run."); diff --git a/src/thread/SDL_thread_c.h b/src/thread/SDL_thread_c.h index 578c09af8..65514a520 100644 --- a/src/thread/SDL_thread_c.h +++ b/src/thread/SDL_thread_c.h @@ -40,6 +40,8 @@ #include "stdcpp/SDL_systhread_c.h" #elif SDL_THREAD_OS2 #include "os2/SDL_systhread_c.h" +#elif SDL_THREAD_NGAGE +#include "ngage/SDL_systhread_c.h" #elif SDL_THREAD_SWITCH #include "switch/SDL_systhread_c.h" #else diff --git a/src/thread/ngage/SDL_sysmutex.cpp b/src/thread/ngage/SDL_sysmutex.cpp new file mode 100644 index 000000000..34cf4510d --- /dev/null +++ b/src/thread/ngage/SDL_sysmutex.cpp @@ -0,0 +1,123 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + 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" + +/* An implementation of mutexes using the Symbian API. */ + +#include + +#include "SDL_thread.h" +#include "SDL_systhread_c.h" + +struct SDL_mutex +{ + TInt handle; +}; + +extern TInt CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny*, TAny*); + +static TInt NewMutex(const TDesC& aName, TAny* aPtr1, TAny*) +{ + return ((RMutex*)aPtr1)->CreateGlobal(aName); +} + +/* Create a mutex */ +SDL_mutex * +SDL_CreateMutex(void) +{ + RMutex rmutex; + + TInt status = CreateUnique(NewMutex, &rmutex, NULL); + if(status != KErrNone) + { + SDL_SetError("Couldn't create mutex."); + } + SDL_mutex* mutex = new /*(ELeave)*/ SDL_mutex; + mutex->handle = rmutex.Handle(); + return(mutex); +} + +/* Free the mutex */ +void +SDL_DestroyMutex(SDL_mutex * mutex) +{ + if (mutex) + { + RMutex rmutex; + rmutex.SetHandle(mutex->handle); + rmutex.Signal(); + rmutex.Close(); + delete(mutex); + mutex = NULL; + } +} + +/* Try to lock the mutex */ +#if 0 +int +SDL_TryLockMutex(SDL_mutex * mutex) +{ + if (mutex == NULL) + { + SDL_SetError("Passed a NULL mutex."); + return -1; + } + + // Not yet implemented. + return 0; +} +#endif + +/* Lock the mutex */ +int +SDL_LockMutex(SDL_mutex * mutex) +{ + if (mutex == NULL) + { + SDL_SetError("Passed a NULL mutex."); + return -1; + } + + RMutex rmutex; + rmutex.SetHandle(mutex->handle); + rmutex.Wait(); + + return(0); +} + +/* Unlock the mutex */ +int +SDL_UnlockMutex(SDL_mutex * mutex) +{ + if ( mutex == NULL ) + { + SDL_SetError("Passed a NULL mutex."); + return -1; + } + + RMutex rmutex; + rmutex.SetHandle(mutex->handle); + rmutex.Signal(); + + return(0); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/ngage/SDL_syssem.cpp b/src/thread/ngage/SDL_syssem.cpp new file mode 100644 index 000000000..ab277ca5d --- /dev/null +++ b/src/thread/ngage/SDL_syssem.cpp @@ -0,0 +1,195 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + 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" + +/* An implementation of semaphores using the Symbian API. */ + +#include + +#include "SDL_error.h" +#include "SDL_thread.h" + +#define SDL_MUTEX_TIMEOUT -2 + +struct SDL_semaphore +{ + TInt handle; + TInt count; +}; + +struct TInfo +{ + TInfo(TInt aTime, TInt aHandle) : + iTime(aTime), iHandle(aHandle), iVal(0) {} + TInt iTime; + TInt iHandle; + TInt iVal; +}; + +extern TInt CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny*, TAny*); + +static TBool RunThread(TAny* aInfo) +{ + TInfo* info = STATIC_CAST(TInfo*, aInfo); + User::After(info->iTime); + RSemaphore sema; + sema.SetHandle(info->iHandle); + sema.Signal(); + info->iVal = SDL_MUTEX_TIMEOUT; + return 0; +} + +static TInt +NewThread(const TDesC& aName, TAny* aPtr1, TAny* aPtr2) +{ + return ((RThread*)(aPtr1))->Create + (aName, + RunThread, + KDefaultStackSize, + NULL, + aPtr2); +} + +static TInt NewSema(const TDesC& aName, TAny* aPtr1, TAny* aPtr2) +{ + TInt value = *((TInt*) aPtr2); + return ((RSemaphore*)aPtr1)->CreateGlobal(aName, value); +} + +static void WaitAll(SDL_sem *sem) +{ + RSemaphore sema; + sema.SetHandle(sem->handle); + sema.Wait(); + while(sem->count < 0) + { + sema.Wait(); + } +} + +SDL_sem * +SDL_CreateSemaphore(Uint32 initial_value) +{ + RSemaphore s; + TInt status = CreateUnique(NewSema, &s, &initial_value); + if(status != KErrNone) + { + SDL_SetError("Couldn't create semaphore"); + } + SDL_semaphore* sem = new /*(ELeave)*/ SDL_semaphore; + sem->handle = s.Handle(); + sem->count = initial_value; + return(sem); +} + +void +SDL_DestroySemaphore(SDL_sem * sem) +{ + if (sem) + { + RSemaphore sema; + sema.SetHandle(sem->handle); + sema.Signal(sema.Count()); + sema.Close(); + delete sem; + sem = NULL; + } +} + +int +SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) +{ + if (! sem) + { + SDL_SetError("Passed a NULL sem"); + return -1; + } + + if (timeout == SDL_MUTEX_MAXWAIT) + { + WaitAll(sem); + return SDL_MUTEX_MAXWAIT; + } + + RThread thread; + TInfo* info = new (ELeave)TInfo(timeout, sem->handle); + TInt status = CreateUnique(NewThread, &thread, info); + + if(status != KErrNone) + { + return status; + } + + thread.Resume(); + WaitAll(sem); + + if(thread.ExitType() == EExitPending) + { + thread.Kill(SDL_MUTEX_TIMEOUT); + } + + thread.Close(); + return info->iVal; +} + +int +SDL_SemTryWait(SDL_sem *sem) +{ + if(sem->count > 0) + { + sem->count--; + } + return SDL_MUTEX_TIMEOUT; +} + +int +SDL_SemWait(SDL_sem * sem) +{ + return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); +} + +Uint32 +SDL_SemValue(SDL_sem * sem) +{ + if (! sem) + { + SDL_SetError("Passed a NULL sem."); + return 0; + } + return sem->count; +} + +int +SDL_SemPost(SDL_sem * sem) +{ + if (! sem) + { + SDL_SetError("Passed a NULL sem."); + return -1; + } + sem->count++; + RSemaphore sema; + sema.SetHandle(sem->handle); + sema.Signal(); + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/ngage/SDL_systhread.cpp b/src/thread/ngage/SDL_systhread.cpp new file mode 100644 index 000000000..f2c30f7b6 --- /dev/null +++ b/src/thread/ngage/SDL_systhread.cpp @@ -0,0 +1,134 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_THREAD_NGAGE + +/* N-Gage thread management routines for SDL */ + +#include + +extern "C" { +#undef NULL +#include "SDL_error.h" +#include "SDL_thread.h" +#include "../SDL_systhread.h" +#include "../SDL_thread_c.h" +}; + +static int object_count; + +static int +RunThread(TAny* data) +{ + SDL_RunThread((SDL_Thread*)data); + return(0); +} + +static TInt +NewThread(const TDesC& aName, TAny* aPtr1, TAny* aPtr2) +{ + return ((RThread*)(aPtr1))->Create + (aName, + RunThread, + KDefaultStackSize, + NULL, + aPtr2); +} + +int +CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny* aPtr1, TAny* aPtr2) +{ + TBuf<16> name; + TInt status = KErrNone; + do + { + object_count++; + name.Format(_L("SDL_%x"), object_count); + status = aFunc(name, aPtr1, aPtr2); + } + while(status == KErrAlreadyExists); + return status; +} + +int +SDL_SYS_CreateThread(SDL_Thread *thread) +{ + RThread rthread; + + TInt status = CreateUnique(NewThread, &rthread, thread); + if (status != KErrNone) + { + delete(((RThread*)(thread->handle))); + thread->handle = NULL; + SDL_SetError("Not enough resources to create thread"); + return(-1); + } + + rthread.Resume(); + thread->handle = rthread.Handle(); + return(0); +} + +void +SDL_SYS_SetupThread(const char *name) +{ + return; +} + +SDL_threadID +SDL_ThreadID(void) +{ + RThread current; + TThreadId id = current.Id(); + return id; +} + +int +SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) +{ + return (0); +} + +void +SDL_SYS_WaitThread(SDL_Thread * thread) +{ + RThread t; + t.Open(thread->threadid); + if(t.ExitReason() == EExitPending) + { + TRequestStatus status; + t.Logon(status); + User::WaitForRequest(status); + } + t.Close(); +} + +void +SDL_SYS_DetachThread(SDL_Thread * thread) +{ + return; +} + +#endif /* SDL_THREAD_NGAGE */ + +/* vim: ts=4 sw=4 + */ diff --git a/src/thread/ngage/SDL_systhread_c.h b/src/thread/ngage/SDL_systhread_c.h new file mode 100644 index 000000000..dedceb396 --- /dev/null +++ b/src/thread/ngage/SDL_systhread_c.h @@ -0,0 +1,25 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + 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" + +typedef int SYS_ThreadHandle; + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/timer/ngage/SDL_systimer.cpp b/src/timer/ngage/SDL_systimer.cpp new file mode 100644 index 000000000..543d8494d --- /dev/null +++ b/src/timer/ngage/SDL_systimer.cpp @@ -0,0 +1,100 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if defined(SDL_TIMER_NGAGE) + +#include +#include + +#include "SDL_timer.h" + +static SDL_bool ticks_started = SDL_FALSE; +static TUint start = 0; +static TInt tickPeriodMilliSeconds; + +#ifdef __cplusplus +extern "C" { +#endif + +void +SDL_TicksInit(void) +{ + if (ticks_started) + { + return; + } + ticks_started = SDL_TRUE; + start = User::TickCount(); + + TTimeIntervalMicroSeconds32 period; + TInt tmp = UserHal::TickPeriod(period); + + (void)tmp; /* Suppress redundant warning. */ + + tickPeriodMilliSeconds = period.Int() / 1000; +} + +void +SDL_TicksQuit(void) +{ + ticks_started = SDL_FALSE; +} + +Uint64 +SDL_GetTicks64(void) +{ + if (! ticks_started) + { + SDL_TicksInit(); + } + + TUint deltaTics = User::TickCount() - start; + + // Overlaps early, but should do the trick for now. + return (Uint64)(deltaTics * tickPeriodMilliSeconds); +} + +Uint64 +SDL_GetPerformanceCounter(void) +{ + return (Uint64)User::TickCount(); +} + +Uint64 +SDL_GetPerformanceFrequency(void) +{ + return 1000000; +} + +void +SDL_Delay(Uint32 ms) +{ + User::After(TTimeIntervalMicroSeconds32(ms * 1000)); +} + +#ifdef __cplusplus +} +#endif + +#endif /* SDL_TIMER_NGAGE */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/SDL_RLEaccel.c b/src/video/SDL_RLEaccel.c index 983c9d914..b67b765e9 100644 --- a/src/video/SDL_RLEaccel.c +++ b/src/video/SDL_RLEaccel.c @@ -92,10 +92,6 @@ #include "SDL_blit.h" #include "SDL_RLEaccel_c.h" -#ifndef MIN -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#endif - #define PIXEL_COPY(to, from, len, bpp) \ SDL_memcpy(to, from, (size_t)(len) * (bpp)) @@ -1161,13 +1157,13 @@ RLEAlphaSurface(SDL_Surface * surface) ADD_OPAQUE_COUNTS(max_opaque_run, 0); skip -= max_opaque_run; } - len = MIN(run, max_opaque_run); + len = SDL_min(run, max_opaque_run); ADD_OPAQUE_COUNTS(skip, len); dst += copy_opaque(dst, src + runstart, len, sf, df); runstart += len; run -= len; while (run) { - len = MIN(run, max_opaque_run); + len = SDL_min(run, max_opaque_run); ADD_OPAQUE_COUNTS(0, len); dst += copy_opaque(dst, src + runstart, len, sf, df); runstart += len; @@ -1195,13 +1191,13 @@ RLEAlphaSurface(SDL_Surface * surface) ADD_TRANSL_COUNTS(max_transl_run, 0); skip -= max_transl_run; } - len = MIN(run, max_transl_run); + len = SDL_min(run, max_transl_run); ADD_TRANSL_COUNTS(skip, len); dst += copy_transl(dst, src + runstart, len, sf, df); runstart += len; run -= len; while (run) { - len = MIN(run, max_transl_run); + len = SDL_min(run, max_transl_run); ADD_TRANSL_COUNTS(0, len); dst += copy_transl(dst, src + runstart, len, sf, df); runstart += len; @@ -1222,9 +1218,13 @@ RLEAlphaSurface(SDL_Surface * surface) /* Now that we have it encoded, release the original pixels */ if (!(surface->flags & SDL_PREALLOC)) { - SDL_SIMDFree(surface->pixels); + if (surface->flags & SDL_SIMD_ALIGNED) { + SDL_SIMDFree(surface->pixels); + surface->flags &= ~SDL_SIMD_ALIGNED; + } else { + SDL_free(surface->pixels); + } surface->pixels = NULL; - surface->flags &= ~SDL_SIMD_ALIGNED; } /* reallocate the buffer to release unused memory */ @@ -1359,14 +1359,14 @@ RLEColorkeySurface(SDL_Surface * surface) ADD_COUNTS(maxn, 0); skip -= maxn; } - len = MIN(run, maxn); + len = SDL_min(run, maxn); ADD_COUNTS(skip, len); SDL_memcpy(dst, srcbuf + runstart * bpp, len * bpp); dst += len * bpp; run -= len; runstart += len; while (run) { - len = MIN(run, maxn); + len = SDL_min(run, maxn); ADD_COUNTS(0, len); SDL_memcpy(dst, srcbuf + runstart * bpp, len * bpp); dst += len * bpp; @@ -1386,9 +1386,13 @@ RLEColorkeySurface(SDL_Surface * surface) /* Now that we have it encoded, release the original pixels */ if (!(surface->flags & SDL_PREALLOC)) { - SDL_SIMDFree(surface->pixels); + if (surface->flags & SDL_SIMD_ALIGNED) { + SDL_SIMDFree(surface->pixels); + surface->flags &= ~SDL_SIMD_ALIGNED; + } else { + SDL_free(surface->pixels); + } surface->pixels = NULL; - surface->flags &= ~SDL_SIMD_ALIGNED; } /* reallocate the buffer to release unused memory */ diff --git a/src/video/SDL_blit_1.c b/src/video/SDL_blit_1.c index d5030cfb1..2c353fd27 100644 --- a/src/video/SDL_blit_1.c +++ b/src/video/SDL_blit_1.c @@ -50,7 +50,7 @@ Blit1to1(SDL_BlitInfo * info) while (height--) { #ifdef USE_DUFFS_LOOP - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { *dst = map[*src]; @@ -58,7 +58,7 @@ Blit1to1(SDL_BlitInfo * info) dst++; src++; , width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ #else for (c = width; c; --c) { *dst = map[*src]; @@ -103,14 +103,14 @@ Blit1to2(SDL_BlitInfo * info) #ifdef USE_DUFFS_LOOP while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { *(Uint16 *)dst = map[*src++]; dst += 2; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -210,7 +210,7 @@ Blit1to3(SDL_BlitInfo * info) while (height--) { #ifdef USE_DUFFS_LOOP - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { o = *src * 4; @@ -221,7 +221,7 @@ Blit1to3(SDL_BlitInfo * info) src++; dst += 3; , width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ #else for (c = width; c; --c) { o = *src * 4; @@ -259,11 +259,11 @@ Blit1to4(SDL_BlitInfo * info) while (height--) { #ifdef USE_DUFFS_LOOP - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( *dst++ = map[*src++]; , width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ #else for (c = width / 4; c; --c) { *dst++ = map[*src++]; @@ -299,7 +299,7 @@ Blit1to1Key(SDL_BlitInfo * info) if (palmap) { while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { if ( *src != ckey ) { @@ -309,13 +309,13 @@ Blit1to1Key(SDL_BlitInfo * info) src++; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } } else { while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { if ( *src != ckey ) { @@ -325,7 +325,7 @@ Blit1to1Key(SDL_BlitInfo * info) src++; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -348,7 +348,7 @@ Blit1to2Key(SDL_BlitInfo * info) dstskip /= 2; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { if ( *src != ckey ) { @@ -358,7 +358,7 @@ Blit1to2Key(SDL_BlitInfo * info) dstp++; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dstp += dstskip; } @@ -378,7 +378,7 @@ Blit1to3Key(SDL_BlitInfo * info) int o; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { if ( *src != ckey ) { @@ -391,7 +391,7 @@ Blit1to3Key(SDL_BlitInfo * info) dst += 3; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -413,7 +413,7 @@ Blit1to4Key(SDL_BlitInfo * info) dstskip /= 4; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { if ( *src != ckey ) { @@ -423,7 +423,7 @@ Blit1to4Key(SDL_BlitInfo * info) dstp++; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dstp += dstskip; } @@ -450,7 +450,7 @@ Blit1toNAlpha(SDL_BlitInfo * info) dstbpp = dstfmt->BytesPerPixel; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4( { sR = srcpal[*src].r; @@ -463,7 +463,7 @@ Blit1toNAlpha(SDL_BlitInfo * info) dst += dstbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -491,7 +491,7 @@ Blit1toNAlphaKey(SDL_BlitInfo * info) dstbpp = dstfmt->BytesPerPixel; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { if ( *src != ckey ) { @@ -506,7 +506,7 @@ Blit1toNAlphaKey(SDL_BlitInfo * info) dst += dstbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } diff --git a/src/video/SDL_blit_A.c b/src/video/SDL_blit_A.c index 4c0726eb0..56ba024c9 100644 --- a/src/video/SDL_blit_A.c +++ b/src/video/SDL_blit_A.c @@ -47,7 +47,7 @@ BlitNto1SurfaceAlpha(SDL_BlitInfo * info) const unsigned A = info->a; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4( { DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB); @@ -68,7 +68,7 @@ BlitNto1SurfaceAlpha(SDL_BlitInfo * info) src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -93,7 +93,7 @@ BlitNto1PixelAlpha(SDL_BlitInfo * info) unsigned dR, dG, dB; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4( { DISEMBLE_RGBA(src,srcbpp,srcfmt,Pixel,sR,sG,sB,sA); @@ -114,7 +114,7 @@ BlitNto1PixelAlpha(SDL_BlitInfo * info) src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -141,7 +141,7 @@ BlitNto1SurfaceAlphaKey(SDL_BlitInfo * info) const unsigned A = info->a; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB); @@ -164,7 +164,7 @@ BlitNto1SurfaceAlphaKey(SDL_BlitInfo * info) src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -348,7 +348,7 @@ BlitRGBtoRGBPixelAlphaMMX(SDL_BlitInfo * info) multmask2 = 0x00FF00FF00FF00FFULL; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4({ Uint32 alpha = *srcp & amask; if (alpha == 0) { @@ -382,7 +382,7 @@ BlitRGBtoRGBPixelAlphaMMX(SDL_BlitInfo * info) ++srcp; ++dstp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } @@ -467,14 +467,14 @@ BlitRGBtoRGBSurfaceAlpha128(SDL_BlitInfo * info) int dstskip = info->dst_skip >> 2; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4({ Uint32 s = *srcp++; Uint32 d = *dstp; *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) + (s & d & 0x00010101)) | 0xff000000; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } @@ -500,7 +500,7 @@ BlitRGBtoRGBSurfaceAlpha(SDL_BlitInfo * info) Uint32 d1; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4({ s = *srcp; d = *dstp; @@ -515,7 +515,7 @@ BlitRGBtoRGBSurfaceAlpha(SDL_BlitInfo * info) ++srcp; ++dstp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } @@ -534,7 +534,7 @@ BlitRGBtoRGBPixelAlpha(SDL_BlitInfo * info) int dstskip = info->dst_skip >> 2; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4({ Uint32 dalpha; Uint32 d; @@ -569,7 +569,7 @@ BlitRGBtoRGBPixelAlpha(SDL_BlitInfo * info) ++srcp; ++dstp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } @@ -587,7 +587,7 @@ BlitRGBtoBGRPixelAlpha(SDL_BlitInfo * info) int dstskip = info->dst_skip >> 2; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4({ Uint32 dalpha; Uint32 d; @@ -624,7 +624,7 @@ BlitRGBtoBGRPixelAlpha(SDL_BlitInfo * info) ++srcp; ++dstp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } @@ -654,7 +654,7 @@ BlitRGBtoRGBPixelAlphaMMX3DNOW(SDL_BlitInfo * info) multmask2 = 0x00FF00FF00FF00FFULL; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4({ Uint32 alpha; @@ -694,7 +694,7 @@ BlitRGBtoRGBPixelAlphaMMX3DNOW(SDL_BlitInfo * info) ++srcp; ++dstp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } @@ -848,7 +848,7 @@ Blit565to565SurfaceAlphaMMX(SDL_BlitInfo * info) bmask = _mm_set_pi32(0x001F001F, 0x001F001F); /* MASKBLUE -> bmask */ while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP_124( { s = *srcp++; @@ -944,7 +944,7 @@ Blit565to565SurfaceAlphaMMX(SDL_BlitInfo * info) srcp += 4; dstp += 4; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } @@ -986,7 +986,7 @@ Blit555to555SurfaceAlphaMMX(SDL_BlitInfo * info) bmask = _mm_set_pi32(0x001F001F, 0x001F001F); /* MASKBLUE -> bmask */ while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP_124( { s = *srcp++; @@ -1082,7 +1082,7 @@ Blit555to555SurfaceAlphaMMX(SDL_BlitInfo * info) srcp += 4; dstp += 4; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } @@ -1109,7 +1109,7 @@ Blit565to565SurfaceAlpha(SDL_BlitInfo * info) alpha >>= 3; /* downscale alpha to 5 bits */ while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4({ Uint32 s = *srcp++; Uint32 d = *dstp; @@ -1124,7 +1124,7 @@ Blit565to565SurfaceAlpha(SDL_BlitInfo * info) d &= 0x07e0f81f; *dstp++ = (Uint16)(d | d >> 16); }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } @@ -1148,7 +1148,7 @@ Blit555to555SurfaceAlpha(SDL_BlitInfo * info) alpha >>= 3; /* downscale alpha to 5 bits */ while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4({ Uint32 s = *srcp++; Uint32 d = *dstp; @@ -1163,7 +1163,7 @@ Blit555to555SurfaceAlpha(SDL_BlitInfo * info) d &= 0x03e07c1f; *dstp++ = (Uint16)(d | d >> 16); }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } @@ -1182,7 +1182,7 @@ BlitARGBto565PixelAlpha(SDL_BlitInfo * info) int dstskip = info->dst_skip >> 1; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4({ Uint32 s = *srcp; unsigned alpha = s >> 27; /* downscale alpha to 5 bits */ @@ -1210,7 +1210,7 @@ BlitARGBto565PixelAlpha(SDL_BlitInfo * info) srcp++; dstp++; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } @@ -1228,7 +1228,7 @@ BlitARGBto555PixelAlpha(SDL_BlitInfo * info) int dstskip = info->dst_skip >> 1; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4({ unsigned alpha; Uint32 s = *srcp; @@ -1257,7 +1257,7 @@ BlitARGBto555PixelAlpha(SDL_BlitInfo * info) srcp++; dstp++; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } @@ -1284,7 +1284,7 @@ BlitNtoNSurfaceAlpha(SDL_BlitInfo * info) if (sA) { while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4( { DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB); @@ -1295,7 +1295,7 @@ BlitNtoNSurfaceAlpha(SDL_BlitInfo * info) dst += dstbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -1323,7 +1323,7 @@ BlitNtoNSurfaceAlphaKey(SDL_BlitInfo * info) const unsigned sA = info->a; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4( { RETRIEVE_RGB_PIXEL(src, srcbpp, Pixel); @@ -1337,7 +1337,7 @@ BlitNtoNSurfaceAlphaKey(SDL_BlitInfo * info) dst += dstbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -1366,7 +1366,7 @@ BlitNtoNPixelAlpha(SDL_BlitInfo * info) dstbpp = dstfmt->BytesPerPixel; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4( { DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA); @@ -1379,7 +1379,7 @@ BlitNtoNPixelAlpha(SDL_BlitInfo * info) dst += dstbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } diff --git a/src/video/SDL_blit_N.c b/src/video/SDL_blit_N.c index e3b6c96a3..ae9c30882 100644 --- a/src/video/SDL_blit_N.c +++ b/src/video/SDL_blit_N.c @@ -1008,11 +1008,11 @@ Blit_RGB888_index8(SDL_BlitInfo * info) if (map == NULL) { while (height--) { #ifdef USE_DUFFS_LOOP - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( RGB888_RGB332(*dst++, *src); , width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ #else for (c = width / 4; c; --c) { /* Pack RGB into 8bit pixel */ @@ -1044,13 +1044,13 @@ Blit_RGB888_index8(SDL_BlitInfo * info) while (height--) { #ifdef USE_DUFFS_LOOP - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( RGB888_RGB332(Pixel, *src); *dst++ = map[Pixel]; ++src; , width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ #else for (c = width / 4; c; --c) { /* Pack RGB into 8bit pixel */ @@ -1118,11 +1118,11 @@ Blit_RGB101010_index8(SDL_BlitInfo * info) if (map == NULL) { while (height--) { #ifdef USE_DUFFS_LOOP - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( RGB101010_RGB332(*dst++, *src); , width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ #else for (c = width / 4; c; --c) { /* Pack RGB into 8bit pixel */ @@ -1154,13 +1154,13 @@ Blit_RGB101010_index8(SDL_BlitInfo * info) while (height--) { #ifdef USE_DUFFS_LOOP - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( RGB101010_RGB332(Pixel, *src); *dst++ = map[Pixel]; ++src; , width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ #else for (c = width / 4; c; --c) { /* Pack RGB into 8bit pixel */ @@ -1235,13 +1235,13 @@ Blit_RGB888_RGB555(SDL_BlitInfo * info) #ifdef USE_DUFFS_LOOP while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( RGB888_RGB555(dst, src); ++src; ++dst; , width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -1361,13 +1361,13 @@ Blit_RGB888_RGB565(SDL_BlitInfo * info) #ifdef USE_DUFFS_LOOP while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( RGB888_RGB565(dst, src); ++src; ++dst; , width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -1476,14 +1476,14 @@ Blit_RGB565_32(SDL_BlitInfo * info, const Uint32 * map) #ifdef USE_DUFFS_LOOP while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { *dst++ = RGB565_32(dst, src, map); src += 2; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -2088,7 +2088,7 @@ Blit_RGB555_ARGB1555(SDL_BlitInfo * info) Uint16 mask = ((Uint32)info->a >> dstfmt->Aloss) << dstfmt->Ashift; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { *dst = *src | mask; @@ -2096,7 +2096,7 @@ Blit_RGB555_ARGB1555(SDL_BlitInfo * info) ++src; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src = (Uint16 *) ((Uint8 *) src + srcskip); dst = (Uint16 *) ((Uint8 *) dst + dstskip); } @@ -2132,7 +2132,7 @@ BlitNto1(SDL_BlitInfo * info) if (map == NULL) { while (height--) { #ifdef USE_DUFFS_LOOP - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB); @@ -2145,7 +2145,7 @@ BlitNto1(SDL_BlitInfo * info) dst++; src += srcbpp; , width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ #else for (c = width; c; --c) { DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB); @@ -2164,7 +2164,7 @@ BlitNto1(SDL_BlitInfo * info) } else { while (height--) { #ifdef USE_DUFFS_LOOP - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB); @@ -2177,7 +2177,7 @@ BlitNto1(SDL_BlitInfo * info) dst++; src += srcbpp; , width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ #else for (c = width; c; --c) { DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB); @@ -2214,7 +2214,7 @@ Blit4to4MaskAlpha(SDL_BlitInfo * info) Uint32 mask = ((Uint32)info->a >> dstfmt->Aloss) << dstfmt->Ashift; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { *dst = *src | mask; @@ -2222,7 +2222,7 @@ Blit4to4MaskAlpha(SDL_BlitInfo * info) ++src; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src = (Uint32 *) ((Uint8 *) src + srcskip); dst = (Uint32 *) ((Uint8 *) dst + dstskip); } @@ -2231,7 +2231,7 @@ Blit4to4MaskAlpha(SDL_BlitInfo * info) Uint32 mask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { *dst = *src & mask; @@ -2239,7 +2239,7 @@ Blit4to4MaskAlpha(SDL_BlitInfo * info) ++src; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src = (Uint32 *) ((Uint8 *) src + srcskip); dst = (Uint32 *) ((Uint8 *) dst + dstskip); } @@ -2259,7 +2259,7 @@ Blit4to4CopyAlpha(SDL_BlitInfo * info) /* RGBA->RGBA, COPY_ALPHA */ while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { *dst = *src; @@ -2267,7 +2267,7 @@ Blit4to4CopyAlpha(SDL_BlitInfo * info) ++src; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src = (Uint32 *) ((Uint8 *) src + srcskip); dst = (Uint32 *) ((Uint8 *) dst + dstskip); } @@ -2380,7 +2380,7 @@ BlitNtoN(SDL_BlitInfo * info) get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, &alpha_channel); while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { dst[0] = src[p0]; @@ -2391,7 +2391,7 @@ BlitNtoN(SDL_BlitInfo * info) src += 4; dst += 4; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -2408,7 +2408,7 @@ BlitNtoN(SDL_BlitInfo * info) get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, NULL); while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { dst[0] = src[p0]; @@ -2417,7 +2417,7 @@ BlitNtoN(SDL_BlitInfo * info) src += 4; dst += 3; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -2434,7 +2434,7 @@ BlitNtoN(SDL_BlitInfo * info) get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, &alpha_channel); while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { dst[0] = src[p0]; @@ -2445,7 +2445,7 @@ BlitNtoN(SDL_BlitInfo * info) src += 3; dst += 4; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -2454,7 +2454,7 @@ BlitNtoN(SDL_BlitInfo * info) #endif while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint32 Pixel; @@ -2467,7 +2467,7 @@ BlitNtoN(SDL_BlitInfo * info) src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -2499,7 +2499,7 @@ BlitNtoNCopyAlpha(SDL_BlitInfo * info) get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, NULL); while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { dst[0] = src[p0]; @@ -2509,7 +2509,7 @@ BlitNtoNCopyAlpha(SDL_BlitInfo * info) src += 4; dst += 4; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -2554,7 +2554,7 @@ BlitNto1Key(SDL_BlitInfo * info) if (palmap == NULL) { while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, @@ -2569,13 +2569,13 @@ BlitNto1Key(SDL_BlitInfo * info) src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } } else { while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, @@ -2590,7 +2590,7 @@ BlitNto1Key(SDL_BlitInfo * info) src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -2615,7 +2615,7 @@ Blit2to2Key(SDL_BlitInfo * info) ckey &= rgbmask; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { if ( (*srcp & rgbmask) != ckey ) { @@ -2625,7 +2625,7 @@ Blit2to2Key(SDL_BlitInfo * info) srcp++; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } @@ -2662,7 +2662,7 @@ BlitNtoNKey(SDL_BlitInfo * info) /* RGB->RGBA, SET_ALPHA */ Uint32 mask = ((Uint32)info->a) << dstfmt->Ashift; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { if ((*src32 & rgbmask) != ckey) { @@ -2671,7 +2671,7 @@ BlitNtoNKey(SDL_BlitInfo * info) ++dst32; ++src32; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src32 = (Uint32 *) ((Uint8 *) src32 + srcskip); dst32 = (Uint32 *) ((Uint8 *) dst32 + dstskip); } @@ -2680,7 +2680,7 @@ BlitNtoNKey(SDL_BlitInfo * info) /* RGBA->RGB, NO_ALPHA */ Uint32 mask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { if ((*src32 & rgbmask) != ckey) { @@ -2689,7 +2689,7 @@ BlitNtoNKey(SDL_BlitInfo * info) ++dst32; ++src32; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src32 = (Uint32 *) ((Uint8 *) src32 + srcskip); dst32 = (Uint32 *) ((Uint8 *) dst32 + dstskip); } @@ -2708,7 +2708,7 @@ BlitNtoNKey(SDL_BlitInfo * info) get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, &alpha_channel); while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint32 *src32 = (Uint32*)src; @@ -2723,7 +2723,7 @@ BlitNtoNKey(SDL_BlitInfo * info) src += 4; dst += 4; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -2746,7 +2746,7 @@ BlitNtoNKey(SDL_BlitInfo * info) #endif while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint8 s0 = src[0]; @@ -2762,7 +2762,7 @@ BlitNtoNKey(SDL_BlitInfo * info) dst += 3; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -2784,7 +2784,7 @@ BlitNtoNKey(SDL_BlitInfo * info) #endif while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint8 s0 = src[0]; @@ -2800,7 +2800,7 @@ BlitNtoNKey(SDL_BlitInfo * info) dst += 3; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -2816,7 +2816,7 @@ BlitNtoNKey(SDL_BlitInfo * info) get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, NULL); while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint32 *src32 = (Uint32*)src; @@ -2828,7 +2828,7 @@ BlitNtoNKey(SDL_BlitInfo * info) src += 4; dst += 3; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -2855,7 +2855,7 @@ BlitNtoNKey(SDL_BlitInfo * info) get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, &alpha_channel); while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint8 s0 = src[0]; @@ -2872,7 +2872,7 @@ BlitNtoNKey(SDL_BlitInfo * info) src += 3; dst += 4; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -2881,7 +2881,7 @@ BlitNtoNKey(SDL_BlitInfo * info) #endif while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint32 Pixel; @@ -2897,7 +2897,7 @@ BlitNtoNKey(SDL_BlitInfo * info) src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -2938,7 +2938,7 @@ BlitNtoNKeyCopyAlpha(SDL_BlitInfo * info) Uint32 *src32 = (Uint32*)src; Uint32 *dst32 = (Uint32*)dst; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { if ((*src32 & rgbmask) != ckey) { @@ -2948,7 +2948,7 @@ BlitNtoNKeyCopyAlpha(SDL_BlitInfo * info) ++dst32; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src32 = (Uint32 *)((Uint8 *)src32 + srcskip); dst32 = (Uint32 *)((Uint8 *)dst32 + dstskip); } @@ -2967,7 +2967,7 @@ BlitNtoNKeyCopyAlpha(SDL_BlitInfo * info) get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, NULL); while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint32 *src32 = (Uint32*)src; @@ -2980,7 +2980,7 @@ BlitNtoNKeyCopyAlpha(SDL_BlitInfo * info) src += 4; dst += 4; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -2989,7 +2989,7 @@ BlitNtoNKeyCopyAlpha(SDL_BlitInfo * info) #endif while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA); @@ -3000,7 +3000,7 @@ BlitNtoNKeyCopyAlpha(SDL_BlitInfo * info) src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -3022,7 +3022,7 @@ Blit2101010toN(SDL_BlitInfo * info) unsigned sR, sG, sB, sA; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Pixel = *(Uint32 *)src; @@ -3032,7 +3032,7 @@ Blit2101010toN(SDL_BlitInfo * info) src += 4; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -3054,7 +3054,7 @@ BlitNto2101010(SDL_BlitInfo * info) unsigned sR, sG, sB, sA; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA); @@ -3064,7 +3064,7 @@ BlitNto2101010(SDL_BlitInfo * info) src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -3096,7 +3096,7 @@ Blit_3or4_to_3or4__same_rgb(SDL_BlitInfo * info) int i2 = srcbpp - 1 - 2; #endif while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint32 *dst32 = (Uint32*)dst; @@ -3107,7 +3107,7 @@ Blit_3or4_to_3or4__same_rgb(SDL_BlitInfo * info) dst += 4; src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -3125,7 +3125,7 @@ Blit_3or4_to_3or4__same_rgb(SDL_BlitInfo * info) int j2 = dstbpp - 1 - 2; #endif while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint8 s0 = src[i0]; @@ -3137,7 +3137,7 @@ Blit_3or4_to_3or4__same_rgb(SDL_BlitInfo * info) dst += dstbpp; src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -3169,7 +3169,7 @@ Blit_3or4_to_3or4__inversed_rgb(SDL_BlitInfo * info) #else int i0 = 3, i1 = 2, i2 = 1, i3 = 0; #endif - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint32 *dst32 = (Uint32*)dst; @@ -3182,7 +3182,7 @@ Blit_3or4_to_3or4__inversed_rgb(SDL_BlitInfo * info) dst += 4; src += 4; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -3197,7 +3197,7 @@ Blit_3or4_to_3or4__inversed_rgb(SDL_BlitInfo * info) int i2 = srcbpp - 1 - 2; #endif while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint32 *dst32 = (Uint32*)dst; @@ -3209,7 +3209,7 @@ Blit_3or4_to_3or4__inversed_rgb(SDL_BlitInfo * info) dst += 4; src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -3228,7 +3228,7 @@ Blit_3or4_to_3or4__inversed_rgb(SDL_BlitInfo * info) int j2 = dstbpp - 1 - 0; #endif while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint8 s0 = src[i0]; @@ -3241,7 +3241,7 @@ Blit_3or4_to_3or4__inversed_rgb(SDL_BlitInfo * info) dst += dstbpp; src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } diff --git a/src/video/SDL_blit_auto.c b/src/video/SDL_blit_auto.c index f64511fcc..f15a43622 100644 --- a/src/video/SDL_blit_auto.c +++ b/src/video/SDL_blit_auto.c @@ -23,7 +23,7 @@ #if SDL_HAVE_BLIT_AUTO -/* *INDENT-OFF* */ +/* *INDENT-OFF* */ /* clang-format off */ #include "SDL_video.h" #include "SDL_blit.h" @@ -7014,7 +7014,7 @@ SDL_BlitFuncEntry SDL_GeneratedBlitFuncTable[] = { { 0, 0, 0, 0, NULL } }; -/* *INDENT-ON* */ +/* *INDENT-ON* */ /* clang-format on */ #endif /* SDL_HAVE_BLIT_AUTO */ diff --git a/src/video/SDL_egl.c b/src/video/SDL_egl.c index e62fe9931..ce9a213e4 100644 --- a/src/video/SDL_egl.c +++ b/src/video/SDL_egl.c @@ -1250,10 +1250,12 @@ EGLSurface SDL_EGL_CreateOffscreenSurface(_THIS, int width, int height) { EGLint attributes[] = { - EGL_WIDTH, width, - EGL_HEIGHT, height, + EGL_WIDTH, 0, + EGL_HEIGHT, 0, EGL_NONE }; + attributes[1] = width; + attributes[3] = height; if (SDL_EGL_ChooseConfig(_this) != 0) { return EGL_NO_SURFACE; diff --git a/src/video/SDL_fillrect.c b/src/video/SDL_fillrect.c index 13872d271..66985117d 100644 --- a/src/video/SDL_fillrect.c +++ b/src/video/SDL_fillrect.c @@ -26,7 +26,7 @@ #ifdef __SSE__ -/* *INDENT-OFF* */ +/* *INDENT-OFF* */ /* clang-format off */ #if defined(_MSC_VER) && !defined(__clang__) #define SSE_BEGIN \ @@ -128,7 +128,7 @@ SDL_FillRect1SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h) DEFINE_SSE_FILLRECT(2, Uint16) DEFINE_SSE_FILLRECT(4, Uint32) -/* *INDENT-ON* */ +/* *INDENT-ON* */ /* clang-format on */ #endif /* __SSE__ */ static void diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index b06cb373f..3c6b252dc 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -237,6 +237,7 @@ struct SDL_VideoDevice int (*SetWindowGammaRamp) (_THIS, SDL_Window * window, const Uint16 * ramp); int (*GetWindowGammaRamp) (_THIS, SDL_Window * window, Uint16 * ramp); void* (*GetWindowICCProfile) (_THIS, SDL_Window * window, size_t* size); + int (*GetWindowDisplayIndex)(_THIS, SDL_Window * window); void (*SetWindowMouseRect)(_THIS, SDL_Window * window); void (*SetWindowMouseGrab) (_THIS, SDL_Window * window, SDL_bool grabbed); void (*SetWindowKeyboardGrab) (_THIS, SDL_Window * window, SDL_bool grabbed); @@ -332,6 +333,7 @@ struct SDL_VideoDevice /* * * */ /* Data common to all drivers */ + SDL_threadID thread; SDL_bool checked_texture_framebuffer; SDL_bool is_dummy; SDL_bool suspend_screensaver; @@ -456,10 +458,13 @@ extern VideoBootStrap VIVANTE_bootstrap; extern VideoBootStrap Emscripten_bootstrap; extern VideoBootStrap QNX_bootstrap; extern VideoBootStrap OFFSCREEN_bootstrap; +extern VideoBootStrap NGAGE_bootstrap; extern VideoBootStrap OS2DIVE_bootstrap; extern VideoBootStrap OS2VMAN_bootstrap; extern VideoBootStrap SWITCH_bootstrap; +/* Use SDL_OnVideoThread() sparingly, to avoid regressions in use cases that currently happen to work */ +extern SDL_bool SDL_OnVideoThread(void); extern SDL_VideoDevice *SDL_GetVideoDevice(void); extern int SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode); extern int SDL_AddVideoDisplay(const SDL_VideoDisplay * display, SDL_bool send_event); @@ -473,6 +478,7 @@ extern SDL_VideoDisplay *SDL_GetDisplay(int displayIndex); extern SDL_VideoDisplay *SDL_GetDisplayForWindow(SDL_Window *window); extern void *SDL_GetDisplayDriverData( int displayIndex ); extern SDL_bool SDL_IsVideoContextExternal(void); +extern int SDL_GetMessageBoxCount(void); extern void SDL_GL_DeduceMaxSupportedESProfile(int* major, int* minor); diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 3bab5c989..54a0ea90b 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -118,6 +118,9 @@ static VideoBootStrap *bootstrap[] = { #if SDL_VIDEO_DRIVER_OFFSCREEN &OFFSCREEN_bootstrap, #endif +#if SDL_VIDEO_DRIVER_NGAGE + &NGAGE_bootstrap, +#endif #if SDL_VIDEO_DRIVER_OS2 &OS2DIVE_bootstrap, &OS2VMAN_bootstrap, @@ -291,6 +294,7 @@ SDL_CreateWindowTexture(SDL_VideoDevice *_this, SDL_Window * window, Uint32 * fo } static SDL_VideoDevice *_this = NULL; +static SDL_atomic_t SDL_messagebox_count; static int SDL_UpdateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, const SDL_Rect * rects, int numrects) @@ -341,7 +345,7 @@ SDL_DestroyWindowTexture(SDL_VideoDevice *unused, SDL_Window * window) SDL_free(data); } -static int +static int SDLCALL cmpmodes(const void *A, const void *B) { const SDL_DisplayMode *a = (const SDL_DisplayMode *) A; @@ -469,6 +473,7 @@ SDL_VideoInit(const char *driver_name) _this = video; _this->name = bootstrap[i]->name; _this->next_object_id = 1; + _this->thread = SDL_ThreadID(); /* Set some very sane GL defaults */ @@ -548,6 +553,12 @@ SDL_GetVideoDevice(void) return _this; } +SDL_bool +SDL_OnVideoThread() +{ + return (_this && SDL_ThreadID() == _this->thread) ? SDL_TRUE : SDL_FALSE; +} + int SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode) { @@ -1063,61 +1074,64 @@ SDL_GetDisplay(int displayIndex) int SDL_GetWindowDisplayIndex(SDL_Window * window) { - int displayIndex; - int i, dist; - int closest = -1; - int closest_dist = 0x7FFFFFFF; - SDL_Point center; - SDL_Point delta; - SDL_Rect rect; - CHECK_WINDOW_MAGIC(window, -1); + if (_this->GetWindowDisplayIndex) { + return _this->GetWindowDisplayIndex(_this, window); + } else { + int displayIndex; + int i, dist; + int closest = -1; + int closest_dist = 0x7FFFFFFF; + SDL_Point center; + SDL_Point delta; + SDL_Rect rect; - if (SDL_WINDOWPOS_ISUNDEFINED(window->x) || - SDL_WINDOWPOS_ISCENTERED(window->x)) { - displayIndex = (window->x & 0xFFFF); - if (displayIndex >= _this->num_displays) { - displayIndex = 0; + if (SDL_WINDOWPOS_ISUNDEFINED(window->x) || + SDL_WINDOWPOS_ISCENTERED(window->x)) { + displayIndex = (window->x & 0xFFFF); + if (displayIndex >= _this->num_displays) { + displayIndex = 0; + } + return displayIndex; } - return displayIndex; - } - if (SDL_WINDOWPOS_ISUNDEFINED(window->y) || - SDL_WINDOWPOS_ISCENTERED(window->y)) { - displayIndex = (window->y & 0xFFFF); - if (displayIndex >= _this->num_displays) { - displayIndex = 0; - } - return displayIndex; - } - - /* Find the display containing the window */ - for (i = 0; i < _this->num_displays; ++i) { - SDL_VideoDisplay *display = &_this->displays[i]; - - if (display->fullscreen_window == window) { - return i; - } - } - center.x = window->x + window->w / 2; - center.y = window->y + window->h / 2; - for (i = 0; i < _this->num_displays; ++i) { - SDL_GetDisplayBounds(i, &rect); - if (SDL_EnclosePoints(¢er, 1, &rect, NULL)) { - return i; + if (SDL_WINDOWPOS_ISUNDEFINED(window->y) || + SDL_WINDOWPOS_ISCENTERED(window->y)) { + displayIndex = (window->y & 0xFFFF); + if (displayIndex >= _this->num_displays) { + displayIndex = 0; + } + return displayIndex; } - delta.x = center.x - (rect.x + rect.w / 2); - delta.y = center.y - (rect.y + rect.h / 2); - dist = (delta.x*delta.x + delta.y*delta.y); - if (dist < closest_dist) { - closest = i; - closest_dist = dist; + /* Find the display containing the window */ + for (i = 0; i < _this->num_displays; ++i) { + SDL_VideoDisplay *display = &_this->displays[i]; + + if (display->fullscreen_window == window) { + return i; + } } + center.x = window->x + window->w / 2; + center.y = window->y + window->h / 2; + for (i = 0; i < _this->num_displays; ++i) { + SDL_GetDisplayBounds(i, &rect); + if (SDL_EnclosePoints(¢er, 1, &rect, NULL)) { + return i; + } + + delta.x = center.x - (rect.x + rect.w / 2); + delta.y = center.y - (rect.y + rect.h / 2); + dist = (delta.x*delta.x + delta.y*delta.y); + if (dist < closest_dist) { + closest = i; + closest_dist = dist; + } + } + if (closest < 0) { + SDL_SetError("Couldn't find any displays"); + } + return closest; } - if (closest < 0) { - SDL_SetError("Couldn't find any displays"); - } - return closest; } SDL_VideoDisplay * @@ -2506,6 +2520,14 @@ SDL_CreateWindowFramebuffer(SDL_Window * window) if (!_this->checked_texture_framebuffer) { SDL_bool attempt_texture_framebuffer = SDL_TRUE; + /* See if the user or application wants to specifically disable the framebuffer */ + const char *hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION); + if (hint) { + if (*hint == '0' || SDL_strcasecmp(hint, "false") == 0) { + attempt_texture_framebuffer = SDL_FALSE; + } + } + if (_this->is_dummy) { /* dummy driver never has GPU support, of course. */ attempt_texture_framebuffer = SDL_FALSE; } @@ -3027,7 +3049,7 @@ SDL_OnWindowFocusGained(SDL_Window * window) if (mouse && mouse->relative_mode) { SDL_SetMouseFocus(window); if (mouse->relative_mode_warp) { - SDL_WarpMouseInWindow(window, window->w/2, window->h/2); + SDL_PerformWarpMouseInWindow(window, window->w/2, window->h/2, SDL_TRUE); } } @@ -4260,6 +4282,12 @@ SDL_IsScreenKeyboardShown(SDL_Window *window) return SDL_FALSE; } +int +SDL_GetMessageBoxCount(void) +{ + return SDL_AtomicGet(&SDL_messagebox_count); +} + #if SDL_VIDEO_DRIVER_ANDROID #include "android/SDL_androidmessagebox.h" #endif @@ -4320,7 +4348,6 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) int retval = -1; SDL_bool relative_mode; int show_cursor_prev; - SDL_bool mouse_captured; SDL_Window *current_window; SDL_MessageBoxData mbdata; @@ -4330,10 +4357,11 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) return SDL_SetError("Invalid number of buttons"); } + (void)SDL_AtomicIncRef(&SDL_messagebox_count); + current_window = SDL_GetKeyboardFocus(); - mouse_captured = current_window && ((SDL_GetWindowFlags(current_window) & SDL_WINDOW_MOUSE_CAPTURE) != 0); relative_mode = SDL_GetRelativeMouseMode(); - SDL_CaptureMouse(SDL_FALSE); + SDL_UpdateMouseCapture(SDL_FALSE); SDL_SetRelativeMouseMode(SDL_FALSE); show_cursor_prev = SDL_ShowCursor(1); SDL_ResetKeyboard(); @@ -4437,15 +4465,15 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) } } + (void)SDL_AtomicDecRef(&SDL_messagebox_count); + if (current_window) { SDL_RaiseWindow(current_window); - if (mouse_captured) { - SDL_CaptureMouse(SDL_TRUE); - } } SDL_ShowCursor(show_cursor_prev); SDL_SetRelativeMouseMode(relative_mode); + SDL_UpdateMouseCapture(SDL_FALSE); return retval; } diff --git a/src/video/SDL_vulkan_internal.h b/src/video/SDL_vulkan_internal.h index 1ec1ab473..ae9b96220 100644 --- a/src/video/SDL_vulkan_internal.h +++ b/src/video/SDL_vulkan_internal.h @@ -34,12 +34,14 @@ #define VK_USE_PLATFORM_ANDROID_KHR #endif #if SDL_VIDEO_DRIVER_COCOA +#define VK_USE_PLATFORM_METAL_EXT #define VK_USE_PLATFORM_MACOS_MVK #endif #if SDL_VIDEO_DRIVER_DIRECTFB #define VK_USE_PLATFORM_DIRECTFB_EXT #endif #if SDL_VIDEO_DRIVER_UIKIT +#define VK_USE_PLATFORM_METAL_EXT #define VK_USE_PLATFORM_IOS_MVK #endif #if SDL_VIDEO_DRIVER_WAYLAND diff --git a/src/video/android/SDL_androidkeyboard.c b/src/video/android/SDL_androidkeyboard.c index 635a22ead..9bb025521 100644 --- a/src/video/android/SDL_androidkeyboard.c +++ b/src/video/android/SDL_androidkeyboard.c @@ -41,12 +41,12 @@ void Android_InitKeyboard(void) static SDL_Scancode Android_Keycodes[] = { SDL_SCANCODE_UNKNOWN, /* AKEYCODE_UNKNOWN */ - SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SOFT_LEFT */ - SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SOFT_RIGHT */ + SDL_SCANCODE_SOFTLEFT, /* AKEYCODE_SOFT_LEFT */ + SDL_SCANCODE_SOFTRIGHT, /* AKEYCODE_SOFT_RIGHT */ SDL_SCANCODE_AC_HOME, /* AKEYCODE_HOME */ SDL_SCANCODE_AC_BACK, /* AKEYCODE_BACK */ - SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CALL */ - SDL_SCANCODE_UNKNOWN, /* AKEYCODE_ENDCALL */ + SDL_SCANCODE_CALL, /* AKEYCODE_CALL */ + SDL_SCANCODE_ENDCALL, /* AKEYCODE_ENDCALL */ SDL_SCANCODE_0, /* AKEYCODE_0 */ SDL_SCANCODE_1, /* AKEYCODE_1 */ SDL_SCANCODE_2, /* AKEYCODE_2 */ diff --git a/src/video/cocoa/SDL_cocoaclipboard.h b/src/video/cocoa/SDL_cocoaclipboard.h index dd5e25224..c8c4d6808 100644 --- a/src/video/cocoa/SDL_cocoaclipboard.h +++ b/src/video/cocoa/SDL_cocoaclipboard.h @@ -24,12 +24,12 @@ #define SDL_cocoaclipboard_h_ /* Forward declaration */ -struct SDL_VideoData; +@class SDL_VideoData; extern int Cocoa_SetClipboardText(_THIS, const char *text); extern char *Cocoa_GetClipboardText(_THIS); extern SDL_bool Cocoa_HasClipboardText(_THIS); -extern void Cocoa_CheckClipboardUpdate(struct SDL_VideoData * data); +extern void Cocoa_CheckClipboardUpdate(SDL_VideoData * data); #endif /* SDL_cocoaclipboard_h_ */ diff --git a/src/video/cocoa/SDL_cocoaclipboard.m b/src/video/cocoa/SDL_cocoaclipboard.m index 1995c7289..e3878ce8f 100644 --- a/src/video/cocoa/SDL_cocoaclipboard.m +++ b/src/video/cocoa/SDL_cocoaclipboard.m @@ -29,7 +29,7 @@ int Cocoa_SetClipboardText(_THIS, const char *text) { @autoreleasepool { - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata; NSPasteboard *pasteboard; NSString *format = NSPasteboardTypeString; NSString *nsstr = [NSString stringWithUTF8String:text]; @@ -38,7 +38,7 @@ Cocoa_SetClipboardText(_THIS, const char *text) } pasteboard = [NSPasteboard generalPasteboard]; - data->clipboard_count = [pasteboard declareTypes:[NSArray arrayWithObject:format] owner:nil]; + data.clipboard_count = [pasteboard declareTypes:[NSArray arrayWithObject:format] owner:nil]; [pasteboard setString:nsstr forType:format]; return 0; @@ -86,7 +86,7 @@ Cocoa_HasClipboardText(_THIS) } void -Cocoa_CheckClipboardUpdate(struct SDL_VideoData * data) +Cocoa_CheckClipboardUpdate(SDL_VideoData * data) { @autoreleasepool { NSPasteboard *pasteboard; @@ -94,11 +94,11 @@ Cocoa_CheckClipboardUpdate(struct SDL_VideoData * data) pasteboard = [NSPasteboard generalPasteboard]; count = [pasteboard changeCount]; - if (count != data->clipboard_count) { - if (data->clipboard_count) { + if (count != data.clipboard_count) { + if (data.clipboard_count) { SDL_SendClipboardUpdate(); } - data->clipboard_count = count; + data.clipboard_count = count; } }} diff --git a/src/video/cocoa/SDL_cocoaevents.m b/src/video/cocoa/SDL_cocoaevents.m index d077bad6e..3a256d2cf 100644 --- a/src/video/cocoa/SDL_cocoaevents.m +++ b/src/video/cocoa/SDL_cocoaevents.m @@ -45,7 +45,7 @@ static SDL_Window *FindSDLWindowForNSWindow(NSWindow *win) SDL_VideoDevice *device = SDL_GetVideoDevice(); if (device && device->windows) { for (sdlwindow = device->windows; sdlwindow; sdlwindow = sdlwindow->next) { - NSWindow *nswindow = ((SDL_WindowData *) sdlwindow->driverdata)->nswindow; + NSWindow *nswindow = ((__bridge SDL_WindowData *) sdlwindow->driverdata).nswindow; if (win == nswindow) return sdlwindow; } @@ -121,7 +121,6 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent) [NSNumber numberWithBool:YES], @"ApplePersistenceIgnoreState", nil]; [[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults]; - [appDefaults release]; } @end // SDLApplication @@ -182,8 +181,6 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent) removeEventHandlerForEventClass:kInternetEventClass andEventID:kAEGetURL]; } - - [super dealloc]; } - (void)windowWillClose:(NSNotification *)notification; @@ -374,9 +371,6 @@ CreateApplicationMenus(void) /* Create the main menu bar */ [NSApp setMainMenu:mainMenu]; - [mainMenu release]; /* we're done with it, let NSApp own it. */ - mainMenu = nil; - /* Create the application menu */ appName = GetApplicationName(); appleMenu = [[NSMenu alloc] initWithTitle:@""]; @@ -396,7 +390,6 @@ CreateApplicationMenus(void) [menuItem setSubmenu:serviceMenu]; [NSApp setServicesMenu:serviceMenu]; - [serviceMenu release]; [appleMenu addItem:[NSMenuItem separatorItem]]; @@ -417,12 +410,9 @@ CreateApplicationMenus(void) menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; [menuItem setSubmenu:appleMenu]; [[NSApp mainMenu] addItem:menuItem]; - [menuItem release]; /* Tell the application object that this is now the application menu */ [NSApp setAppleMenu:appleMenu]; - [appleMenu release]; - /* Create the window menu */ windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; @@ -434,26 +424,21 @@ CreateApplicationMenus(void) [windowMenu addItemWithTitle:@"Zoom" action:@selector(performZoom:) keyEquivalent:@""]; - /* Add the fullscreen toggle menu option, if supported */ - if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) { - /* Cocoa should update the title to Enter or Exit Full Screen automatically. - * But if not, then just fallback to Toggle Full Screen. - */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"Toggle Full Screen" action:@selector(toggleFullScreen:) keyEquivalent:@"f"]; - [menuItem setKeyEquivalentModifierMask:NSEventModifierFlagControl | NSEventModifierFlagCommand]; - [windowMenu addItem:menuItem]; - [menuItem release]; - } + /* Add the fullscreen toggle menu option. */ + /* Cocoa should update the title to Enter or Exit Full Screen automatically. + * But if not, then just fallback to Toggle Full Screen. + */ + menuItem = [[NSMenuItem alloc] initWithTitle:@"Toggle Full Screen" action:@selector(toggleFullScreen:) keyEquivalent:@"f"]; + [menuItem setKeyEquivalentModifierMask:NSEventModifierFlagControl | NSEventModifierFlagCommand]; + [windowMenu addItem:menuItem]; /* Put menu into the menubar */ menuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; [menuItem setSubmenu:windowMenu]; [[NSApp mainMenu] addItem:menuItem]; - [menuItem release]; /* Tell the application object that this is now the window menu */ [NSApp setWindowsMenu:windowMenu]; - [windowMenu release]; } void @@ -518,19 +503,6 @@ Cocoa_RegisterApp(void) int Cocoa_PumpEventsUntilDate(_THIS, NSDate *expiration, bool accumulate) { -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 - /* Update activity every 30 seconds to prevent screensaver */ - SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; - if (_this->suspend_screensaver && !data->screensaver_use_iopm) { - Uint32 now = SDL_GetTicks(); - if (!data->screensaver_activity || - SDL_TICKS_PASSED(now, data->screensaver_activity + 30000)) { - UpdateSystemActivity(UsrActivity); - data->screensaver_activity = now; - } - } -#endif - for ( ; ; ) { NSEvent *event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:expiration inMode:NSDefaultRunLoopMode dequeue:YES ]; if ( event == nil ) { @@ -576,7 +548,7 @@ Cocoa_PumpEvents(_THIS) void Cocoa_SendWakeupEvent(_THIS, SDL_Window *window) { @autoreleasepool { - NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow; + NSWindow *nswindow = ((__bridge SDL_WindowData *) window->driverdata).nswindow; NSEvent* event = [NSEvent otherEventWithType: NSEventTypeApplicationDefined location: NSMakePoint(0,0) @@ -595,15 +567,11 @@ void Cocoa_SuspendScreenSaver(_THIS) { @autoreleasepool { - SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + SDL_VideoData *data = (__bridge SDL_VideoData *)_this->driverdata; - if (!data->screensaver_use_iopm) { - return; - } - - if (data->screensaver_assertion) { - IOPMAssertionRelease(data->screensaver_assertion); - data->screensaver_assertion = 0; + if (data.screensaver_assertion) { + IOPMAssertionRelease(data.screensaver_assertion); + data.screensaver_assertion = kIOPMNullAssertionID; } if (_this->suspend_screensaver) { @@ -612,11 +580,13 @@ Cocoa_SuspendScreenSaver(_THIS) * seen by OS X power users. there's an additional optional human-readable * (localized) reason parameter which we don't set. */ + IOPMAssertionID assertion = kIOPMNullAssertionID; NSString *name = [GetApplicationName() stringByAppendingString:@" using SDL_DisableScreenSaver"]; IOPMAssertionCreateWithDescription(kIOPMAssertPreventUserIdleDisplaySleep, - (CFStringRef) name, + (__bridge CFStringRef) name, NULL, NULL, NULL, 0, NULL, - &data->screensaver_assertion); + &assertion); + data.screensaver_assertion = assertion; } }} diff --git a/src/video/cocoa/SDL_cocoakeyboard.m b/src/video/cocoa/SDL_cocoakeyboard.m index b229ac3f6..59ee39dc0 100644 --- a/src/video/cocoa/SDL_cocoakeyboard.m +++ b/src/video/cocoa/SDL_cocoakeyboard.m @@ -104,8 +104,7 @@ } if (_markedText != aString) { - [_markedText release]; - _markedText = [aString retain]; + _markedText = aString; } _selectedRange = selectedRange; @@ -120,7 +119,6 @@ - (void)unmarkText { - [_markedText release]; _markedText = nil; SDL_SendEditingText("", 0, 0); @@ -142,14 +140,7 @@ aRange.location, aRange.length, windowHeight, NSStringFromRect(rect)); -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 - if (![window respondsToSelector:@selector(convertRectToScreen:)]) { - rect.origin = [window convertBaseToScreen:rect.origin]; - } else -#endif - { - rect = [window convertRectToScreen:rect]; - } + rect = [window convertRectToScreen:rect]; return rect; } @@ -381,14 +372,14 @@ DoSidedModifiers(unsigned short scancode, static void HandleModifiers(_THIS, unsigned short scancode, unsigned int modifierFlags) { - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata; - if (modifierFlags == data->modifierFlags) { + if (modifierFlags == data.modifierFlags) { return; } - DoSidedModifiers(scancode, data->modifierFlags, modifierFlags); - data->modifierFlags = modifierFlags; + DoSidedModifiers(scancode, data.modifierFlags, modifierFlags); + data.modifierFlags = modifierFlags; } static void @@ -402,10 +393,10 @@ UpdateKeymap(SDL_VideoData *data, SDL_bool send_event) /* See if the keymap needs to be updated */ key_layout = TISCopyCurrentKeyboardLayoutInputSource(); - if (key_layout == data->key_layout) { + if (key_layout == data.key_layout) { return; } - data->key_layout = key_layout; + data.key_layout = key_layout; SDL_GetDefaultKeymap(keymap); @@ -461,7 +452,7 @@ cleanup: void Cocoa_InitKeyboard(_THIS) { - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata; UpdateKeymap(data, SDL_FALSE); @@ -473,19 +464,19 @@ Cocoa_InitKeyboard(_THIS) SDL_SetScancodeName(SDL_SCANCODE_RALT, "Right Option"); SDL_SetScancodeName(SDL_SCANCODE_RGUI, "Right Command"); - data->modifierFlags = (unsigned int)[NSEvent modifierFlags]; - SDL_ToggleModState(KMOD_CAPS, (data->modifierFlags & NSEventModifierFlagCapsLock) != 0); + data.modifierFlags = (unsigned int)[NSEvent modifierFlags]; + SDL_ToggleModState(KMOD_CAPS, (data.modifierFlags & NSEventModifierFlagCapsLock) != 0); } void Cocoa_StartTextInput(_THIS) { @autoreleasepool { - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata; SDL_Window *window = SDL_GetKeyboardFocus(); NSWindow *nswindow = nil; if (window) { - nswindow = ((SDL_WindowData*)window->driverdata)->nswindow; + nswindow = ((__bridge SDL_WindowData*)window->driverdata).nswindow; } NSView *parentView = [nswindow contentView]; @@ -495,16 +486,16 @@ Cocoa_StartTextInput(_THIS) * than one copy. When we switched to another window and requesting for * text input, simply remove the field editor from its superview then add * it to the front most window's content view */ - if (!data->fieldEdit) { - data->fieldEdit = + if (!data.fieldEdit) { + data.fieldEdit = [[SDLTranslatorResponder alloc] initWithFrame: NSMakeRect(0.0, 0.0, 0.0, 0.0)]; } - if (![[data->fieldEdit superview] isEqual:parentView]) { + if (![[data.fieldEdit superview] isEqual:parentView]) { /* DEBUG_IME(@"add fieldEdit to window contentView"); */ - [data->fieldEdit removeFromSuperview]; - [parentView addSubview: data->fieldEdit]; - [nswindow makeFirstResponder: data->fieldEdit]; + [data.fieldEdit removeFromSuperview]; + [parentView addSubview: data.fieldEdit]; + [nswindow makeFirstResponder: data.fieldEdit]; } }} @@ -512,32 +503,31 @@ void Cocoa_StopTextInput(_THIS) { @autoreleasepool { - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata; - if (data && data->fieldEdit) { - [data->fieldEdit removeFromSuperview]; - [data->fieldEdit release]; - data->fieldEdit = nil; + if (data && data.fieldEdit) { + [data.fieldEdit removeFromSuperview]; + data.fieldEdit = nil; } }} void Cocoa_SetTextInputRect(_THIS, SDL_Rect *rect) { - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata; if (!rect) { SDL_InvalidParamError("rect"); return; } - [data->fieldEdit setInputRect:rect]; + [data.fieldEdit setInputRect:rect]; } void Cocoa_HandleKeyEvent(_THIS, NSEvent *event) { - SDL_VideoData *data = _this ? ((SDL_VideoData *) _this->driverdata) : NULL; + SDL_VideoData *data = _this ? ((__bridge SDL_VideoData *) _this->driverdata) : nil; if (!data) { return; /* can happen when returning from fullscreen Space on shutdown */ } @@ -575,7 +565,7 @@ Cocoa_HandleKeyEvent(_THIS, NSEvent *event) #endif if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { /* FIXME CW 2007-08-16: only send those events to the field editor for which we actually want text events, not e.g. esc or function keys. Arrow keys in particular seem to produce crashes sometimes. */ - [data->fieldEdit interpretKeyEvents:[NSArray arrayWithObject:event]]; + [data.fieldEdit interpretKeyEvents:[NSArray arrayWithObject:event]]; #if 0 text = [[event characters] UTF8String]; if(text && *text) { diff --git a/src/video/cocoa/SDL_cocoamessagebox.m b/src/video/cocoa/SDL_cocoamessagebox.m index e3fc20b7e..494f88d71 100644 --- a/src/video/cocoa/SDL_cocoamessagebox.m +++ b/src/video/cocoa/SDL_cocoamessagebox.m @@ -45,9 +45,9 @@ /* Retain the NSWindow because we'll show the alert later on the main thread */ if (window) { - nswindow = [((SDL_WindowData *) window->driverdata)->nswindow retain]; + nswindow = ((__bridge SDL_WindowData *) window->driverdata).nswindow; } else { - nswindow = NULL; + nswindow = nil; } } @@ -60,7 +60,7 @@ #ifdef MAC_OS_X_VERSION_10_9 if ([alert respondsToSelector:@selector(beginSheetModalForWindow:completionHandler:)]) { [alert beginSheetModalForWindow:nswindow completionHandler:^(NSModalResponse returnCode) { - clicked = returnCode; + self->clicked = returnCode; }]; } else #endif @@ -75,7 +75,7 @@ SDL_Delay(100); } - [nswindow release]; + nswindow = nil; } else { clicked = [alert runModal]; } @@ -94,7 +94,7 @@ Cocoa_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int *buttonid { Cocoa_RegisterApp(); - NSAlert* alert = [[[NSAlert alloc] init] autorelease]; + NSAlert* alert = [[NSAlert alloc] init]; if (messageboxdata->flags & SDL_MESSAGEBOX_ERROR) { [alert setAlertStyle:NSAlertStyleCritical]; @@ -129,7 +129,7 @@ Cocoa_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int *buttonid } } - SDLMessageBoxPresenter* presenter = [[[SDLMessageBoxPresenter alloc] initWithParentWindow:messageboxdata->window] autorelease]; + SDLMessageBoxPresenter* presenter = [[SDLMessageBoxPresenter alloc] initWithParentWindow:messageboxdata->window]; [presenter showAlert:alert]; diff --git a/src/video/cocoa/SDL_cocoametalview.m b/src/video/cocoa/SDL_cocoametalview.m index 6e33c4899..ebdc921a1 100644 --- a/src/video/cocoa/SDL_cocoametalview.m +++ b/src/video/cocoa/SDL_cocoametalview.m @@ -89,7 +89,7 @@ SDL_MetalViewEventWatch(void *userdata, SDL_Event *event) /* Allow resize. */ self.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; - SDL_AddEventWatch(SDL_MetalViewEventWatch, self); + SDL_AddEventWatch(SDL_MetalViewEventWatch, (__bridge void *)(self)); [self updateDrawableSize]; } @@ -99,8 +99,7 @@ SDL_MetalViewEventWatch(void *userdata, SDL_Event *event) - (void)dealloc { - SDL_DelEventWatch(SDL_MetalViewEventWatch, self); - [super dealloc]; + SDL_DelEventWatch(SDL_MetalViewEventWatch, (__bridge void *)(self)); } - (NSInteger)tag @@ -135,7 +134,7 @@ SDL_MetalView Cocoa_Metal_CreateView(_THIS, SDL_Window * window) { @autoreleasepool { SDL_WindowData* data = (__bridge SDL_WindowData *)window->driverdata; - NSView *view = data->nswindow.contentView; + NSView *view = data.nswindow.contentView; BOOL highDPI = (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) != 0; Uint32 windowID = SDL_GetWindowID(window); SDL_cocoametalview *newview; @@ -151,7 +150,6 @@ Cocoa_Metal_CreateView(_THIS, SDL_Window * window) [view addSubview:newview]; metalview = (SDL_MetalView)CFBridgingRetain(newview); - [newview release]; return metalview; }} @@ -174,7 +172,7 @@ void Cocoa_Metal_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h) { @autoreleasepool { SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata; - NSView *contentView = data->sdlContentView; + NSView *contentView = data.sdlContentView; SDL_cocoametalview* metalview = [contentView viewWithTag:SDL_METALVIEW_TAG]; if (metalview) { CAMetalLayer *layer = (CAMetalLayer*)metalview.layer; @@ -189,11 +187,8 @@ Cocoa_Metal_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h) /* Fall back to the viewport size. */ NSRect viewport = [contentView bounds]; if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { - /* This gives us the correct viewport for a Retina-enabled view, only - * supported on 10.7+. */ - if ([contentView respondsToSelector:@selector(convertRectToBacking:)]) { - viewport = [contentView convertRectToBacking:viewport]; - } + /* This gives us the correct viewport for a Retina-enabled view. */ + viewport = [contentView convertRectToBacking:viewport]; } if (w) { *w = viewport.size.width; diff --git a/src/video/cocoa/SDL_cocoamodes.m b/src/video/cocoa/SDL_cocoamodes.m index 7d19030b2..88284b505 100644 --- a/src/video/cocoa/SDL_cocoamodes.m +++ b/src/video/cocoa/SDL_cocoamodes.m @@ -31,9 +31,6 @@ #include #include -/* we need this for ShowMenuBar() and HideMenuBar(). */ -#include - /* This gets us MAC_OS_X_VERSION_MIN_REQUIRED... */ #include @@ -45,23 +42,6 @@ #endif -static void -Cocoa_ToggleMenuBar(const BOOL show) -{ - /* !!! FIXME: keep an eye on this. - * ShowMenuBar/HideMenuBar is officially unavailable for 64-bit binaries. - * It happens to work, as of 10.7, but we're going to see if - * we can just simply do without it on newer OSes... - */ -#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070) && !defined(__LP64__) - if (show) { - ShowMenuBar(); - } else { - HideMenuBar(); - } -#endif -} - static int CG_SetError(const char *prefix, CGDisplayErr result) { @@ -306,7 +286,7 @@ Cocoa_GetDisplayName(CGDirectDisplayID displayID) /* This API is deprecated in 10.9 with no good replacement (as of 10.15). */ io_service_t servicePort = CGDisplayIOServicePort(displayID); CFDictionaryRef deviceInfo = IODisplayCreateInfoDictionary(servicePort, kIODisplayOnlyPreferredName); - NSDictionary *localizedNames = [(NSDictionary *)deviceInfo objectForKey:[NSString stringWithUTF8String:kDisplayProductName]]; + NSDictionary *localizedNames = [(__bridge NSDictionary *)deviceInfo objectForKey:[NSString stringWithUTF8String:kDisplayProductName]]; const char* displayName = NULL; if ([localizedNames count] > 0) { @@ -497,7 +477,7 @@ Cocoa_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdp CFRelease(dmOptions); } else #endif - if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) { + { // fallback for 10.7 scaleFactor = [screen backingScaleFactor]; displayNativeSize.width = displayNativeSize.width * scaleFactor; @@ -646,10 +626,6 @@ Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) } else { CGDisplayRelease(displaydata->display); } - - if (CGDisplayIsMain(displaydata->display)) { - Cocoa_ToggleMenuBar(YES); - } } else { /* Put up the blanking window (a window above all other windows) */ if (CGDisplayIsMain(displaydata->display)) { @@ -669,11 +645,6 @@ Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) CG_SetError("CGDisplaySwitchToMode()", result); goto ERR_NO_SWITCH; } - - /* Hide the menu bar so it doesn't intercept events */ - if (CGDisplayIsMain(displaydata->display)) { - Cocoa_ToggleMenuBar(NO); - } } /* Fade in again (asynchronously) */ @@ -720,7 +691,6 @@ Cocoa_QuitModes(_THIS) CFRelease(mode->modes); } } - Cocoa_ToggleMenuBar(YES); } #endif /* SDL_VIDEO_DRIVER_COCOA */ diff --git a/src/video/cocoa/SDL_cocoamouse.m b/src/video/cocoa/SDL_cocoamouse.m index 7713fb544..f6534b334 100644 --- a/src/video/cocoa/SDL_cocoamouse.m +++ b/src/video/cocoa/SDL_cocoamouse.m @@ -53,7 +53,7 @@ NSData *cursorData = [NSData dataWithBytesNoCopy:&cursorBytes[0] length:sizeof(cursorBytes) freeWhenDone:NO]; - NSImage *cursorImage = [[[NSImage alloc] initWithData:cursorData] autorelease]; + NSImage *cursorImage = [[NSImage alloc] initWithData:cursorData]; invisibleCursor = [[NSCursor alloc] initWithImage:cursorImage hotSpot:NSZeroPoint]; } @@ -75,8 +75,7 @@ Cocoa_CreateDefaultCursor() if (nscursor) { cursor = SDL_calloc(1, sizeof(*cursor)); if (cursor) { - cursor->driverdata = nscursor; - [nscursor retain]; + cursor->driverdata = (void *)CFBridgingRetain(nscursor); } } @@ -99,15 +98,52 @@ Cocoa_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) if (nscursor) { cursor = SDL_calloc(1, sizeof(*cursor)); if (cursor) { - cursor->driverdata = nscursor; - } else { - [nscursor release]; + cursor->driverdata = (void *)CFBridgingRetain(nscursor); } } return cursor; }} +/* there are .pdf files of some of the cursors we need, installed by default on macOS, but not available through NSCursor. + If we can load them ourselves, use them, otherwise fallback to something standard but not super-great. + Since these are under /System, they should be available even to sandboxed apps. */ +static NSCursor * +LoadHiddenSystemCursor(NSString *cursorName, SEL fallback) +{ + NSString *cursorPath = [@"/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/HIServices.framework/Versions/A/Resources/cursors" stringByAppendingPathComponent:cursorName]; + NSImage *image = [[NSImage alloc] initWithContentsOfFile:[cursorPath stringByAppendingPathComponent:@"cursor.pdf"]]; + if ((image == nil) || (image.valid == NO)) { + return [NSCursor performSelector:fallback]; + } + + NSDictionary *info = [NSDictionary dictionaryWithContentsOfFile:[cursorPath stringByAppendingPathComponent:@"info.plist"]]; + + /* we can't do animation atm. :/ */ + const int frames = [[info valueForKey:@"frames"] integerValue]; + if (frames > 1) { + const NSSize cropped_size = NSMakeSize(image.size.width, (int) (image.size.height / frames)); + NSImage *cropped = [[NSImage alloc] initWithSize:cropped_size]; + if (cropped == nil) { + return [NSCursor performSelector:fallback]; + } + + #ifdef MAC_OS_VERSION_12_0 /* same value as deprecated symbol. */ + const NSCompositingOperation operation = NSCompositingOperationCopy; + #else + const NSCompositingOperation operation = NSCompositeCopy; + #endif + [cropped lockFocus]; + const NSRect cropped_rect = NSMakeRect(0, 0, cropped_size.width, cropped_size.height); + [image drawInRect:cropped_rect fromRect:cropped_rect operation:operation fraction:1]; + [cropped unlockFocus]; + image = cropped; + } + + NSCursor *cursor = [[NSCursor alloc] initWithImage:image hotSpot:NSMakePoint([[info valueForKey:@"hotx"] doubleValue], [[info valueForKey:@"hoty"] doubleValue])]; + return cursor; +} + static SDL_Cursor * Cocoa_CreateSystemCursor(SDL_SystemCursor id) { @autoreleasepool @@ -122,27 +158,29 @@ Cocoa_CreateSystemCursor(SDL_SystemCursor id) case SDL_SYSTEM_CURSOR_IBEAM: nscursor = [NSCursor IBeamCursor]; break; - case SDL_SYSTEM_CURSOR_WAIT: - nscursor = [NSCursor arrowCursor]; - break; case SDL_SYSTEM_CURSOR_CROSSHAIR: nscursor = [NSCursor crosshairCursor]; break; - case SDL_SYSTEM_CURSOR_WAITARROW: - nscursor = [NSCursor arrowCursor]; + case SDL_SYSTEM_CURSOR_WAIT: /* !!! FIXME: this is more like WAITARROW */ + nscursor = LoadHiddenSystemCursor(@"busybutclickable", @selector(arrowCursor)); + break; + case SDL_SYSTEM_CURSOR_WAITARROW: /* !!! FIXME: this is meant to be animated */ + nscursor = LoadHiddenSystemCursor(@"busybutclickable", @selector(arrowCursor)); break; case SDL_SYSTEM_CURSOR_SIZENWSE: + nscursor = LoadHiddenSystemCursor(@"resizenorthwestsoutheast", @selector(closedHandCursor)); + break; case SDL_SYSTEM_CURSOR_SIZENESW: - nscursor = [NSCursor closedHandCursor]; + nscursor = LoadHiddenSystemCursor(@"resizenortheastsouthwest", @selector(closedHandCursor)); break; case SDL_SYSTEM_CURSOR_SIZEWE: - nscursor = [NSCursor resizeLeftRightCursor]; + nscursor = LoadHiddenSystemCursor(@"resizeeastwest", @selector(resizeLeftRightCursor)); break; case SDL_SYSTEM_CURSOR_SIZENS: - nscursor = [NSCursor resizeUpDownCursor]; + nscursor = LoadHiddenSystemCursor(@"resizenorthsouth", @selector(resizeUpDownCursor)); break; case SDL_SYSTEM_CURSOR_SIZEALL: - nscursor = [NSCursor closedHandCursor]; + nscursor = LoadHiddenSystemCursor(@"move", @selector(closedHandCursor)); break; case SDL_SYSTEM_CURSOR_NO: nscursor = [NSCursor operationNotAllowedCursor]; @@ -159,8 +197,7 @@ Cocoa_CreateSystemCursor(SDL_SystemCursor id) cursor = SDL_calloc(1, sizeof(*cursor)); if (cursor) { /* We'll free it later, so retain it here */ - [nscursor retain]; - cursor->driverdata = nscursor; + cursor->driverdata = (void *)CFBridgingRetain(nscursor); } } @@ -171,9 +208,7 @@ static void Cocoa_FreeCursor(SDL_Cursor * cursor) { @autoreleasepool { - NSCursor *nscursor = (NSCursor *)cursor->driverdata; - - [nscursor release]; + CFBridgingRelease(cursor->driverdata); SDL_free(cursor); }} @@ -184,11 +219,11 @@ Cocoa_ShowCursor(SDL_Cursor * cursor) SDL_VideoDevice *device = SDL_GetVideoDevice(); SDL_Window *window = (device ? device->windows : NULL); for (; window != NULL; window = window->next) { - SDL_WindowData *driverdata = (SDL_WindowData *)window->driverdata; + SDL_WindowData *driverdata = (__bridge SDL_WindowData *)window->driverdata; if (driverdata) { - [driverdata->nswindow performSelectorOnMainThread:@selector(invalidateCursorRectsForView:) - withObject:[driverdata->nswindow contentView] - waitUntilDone:NO]; + [driverdata.nswindow performSelectorOnMainThread:@selector(invalidateCursorRectsForView:) + withObject:[driverdata.nswindow contentView] + waitUntilDone:NO]; } } return 0; @@ -214,10 +249,10 @@ Cocoa_WarpMouseGlobal(int x, int y) { SDL_Mouse *mouse = SDL_GetMouse(); if (mouse->focus) { - SDL_WindowData *data = (SDL_WindowData *) mouse->focus->driverdata; - if ([data->listener isMovingOrFocusClickPending]) { + SDL_WindowData *data = (__bridge SDL_WindowData *) mouse->focus->driverdata; + if ([data.listener isMovingOrFocusClickPending]) { DLog("Postponing warp, window being moved or focused."); - [data->listener setPendingMoveX:x Y:y]; + [data.listener setPendingMoveX:x Y:y]; return 0; } } @@ -259,22 +294,6 @@ Cocoa_WarpMouse(SDL_Window * window, int x, int y) static int Cocoa_SetRelativeMouseMode(SDL_bool enabled) { - /* We will re-apply the relative mode when the window gets focus, if it - * doesn't have focus right now. - */ - SDL_Window *window = SDL_GetKeyboardFocus(); - if (!window) { - return 0; - } - - /* We will re-apply the relative mode when the window finishes being moved, - * if it is being moved right now. - */ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - if ([data->listener isMovingOrFocusClickPending]) { - return 0; - } - CGError result; if (enabled) { DLog("Turning on."); @@ -287,6 +306,22 @@ Cocoa_SetRelativeMouseMode(SDL_bool enabled) return SDL_SetError("CGAssociateMouseAndMouseCursorPosition() failed"); } + /* We will re-apply the non-relative mode when the window gets focus, if it + * doesn't have focus right now. + */ + SDL_Window *window = SDL_GetKeyboardFocus(); + if (!window) { + return 0; + } + + /* We will re-apply the non-relative mode when the window finishes being moved, + * if it is being moved right now. + */ + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; + if ([data.listener isMovingOrFocusClickPending]) { + return 0; + } + /* The hide/unhide calls are redundant most of the time, but they fix * https://bugzilla.libsdl.org/show_bug.cgi?id=2550 */ @@ -360,18 +395,18 @@ Cocoa_HandleTitleButtonEvent(_THIS, NSEvent *event) NSWindow *nswindow = [event window]; for (window = _this->windows; window; window = window->next) { - SDL_WindowData *data = (SDL_WindowData *)window->driverdata; - if (data && data->nswindow == nswindow) { + SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata; + if (data && data.nswindow == nswindow) { switch ([event type]) { case NSEventTypeLeftMouseDown: case NSEventTypeRightMouseDown: case NSEventTypeOtherMouseDown: - [data->listener setFocusClickPending:[event buttonNumber]]; + [data.listener setFocusClickPending:[event buttonNumber]]; break; case NSEventTypeLeftMouseUp: case NSEventTypeRightMouseUp: case NSEventTypeOtherMouseUp: - [data->listener clearFocusClickPending:[event buttonNumber]]; + [data.listener clearFocusClickPending:[event buttonNumber]]; break; default: break; @@ -467,15 +502,13 @@ Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event) CGFloat y = [event deltaY]; SDL_MouseWheelDirection direction = SDL_MOUSEWHEEL_NORMAL; - if ([event respondsToSelector:@selector(isDirectionInvertedFromDevice)]) { - if ([event isDirectionInvertedFromDevice] == YES) { - direction = SDL_MOUSEWHEEL_FLIPPED; - } + if ([event isDirectionInvertedFromDevice] == YES) { + direction = SDL_MOUSEWHEEL_FLIPPED; } /* For discrete scroll events from conventional mice, always send a full tick. For continuous scroll events from trackpads, send fractional deltas for smoother scrolling. */ - if (![event respondsToSelector:@selector(hasPreciseScrollingDeltas)] || ![event hasPreciseScrollingDeltas]) { + if (![event hasPreciseScrollingDeltas]) { if (x > 0) { x = SDL_ceil(x); } else if (x < 0) { diff --git a/src/video/cocoa/SDL_cocoaopengl.m b/src/video/cocoa/SDL_cocoaopengl.m index 9d31b9c22..aa2f51eaa 100644 --- a/src/video/cocoa/SDL_cocoaopengl.m +++ b/src/video/cocoa/SDL_cocoaopengl.m @@ -82,10 +82,10 @@ - (void)setWindow:(SDL_Window *)newWindow { if (self->window) { - SDL_WindowData *oldwindowdata = (SDL_WindowData *)self->window->driverdata; + SDL_WindowData *oldwindowdata = (__bridge SDL_WindowData *)self->window->driverdata; /* Make sure to remove us from the old window's context list, or we'll get scheduled updates from it too. */ - NSMutableArray *contexts = oldwindowdata->nscontexts; + NSMutableArray *contexts = oldwindowdata.nscontexts; @synchronized (contexts) { [contexts removeObject:self]; } @@ -94,11 +94,11 @@ self->window = newWindow; if (newWindow) { - SDL_WindowData *windowdata = (SDL_WindowData *)newWindow->driverdata; - NSView *contentview = windowdata->sdlContentView; + SDL_WindowData *windowdata = (__bridge SDL_WindowData *)newWindow->driverdata; + NSView *contentview = windowdata.sdlContentView; /* Now sign up for scheduled updates for the new window. */ - NSMutableArray *contexts = windowdata->nscontexts; + NSMutableArray *contexts = windowdata.nscontexts; @synchronized (contexts) { [contexts addObject:self]; } @@ -180,10 +180,10 @@ Cocoa_GL_CreateContext(_THIS, SDL_Window * window) { SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata; - SDL_bool lion_or_later = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6; NSOpenGLPixelFormatAttribute attr[32]; NSOpenGLPixelFormat *fmt; SDLOpenGLContext *context; + SDL_GLContext sdlcontext; NSOpenGLContext *share_context = nil; int i = 0; const char *glversion; @@ -213,22 +213,15 @@ Cocoa_GL_CreateContext(_THIS, SDL_Window * window) return NULL; #endif } - if ((_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_CORE) && !lion_or_later) { - SDL_SetError ("OpenGL Core Profile is not supported on this platform version"); - return NULL; - } attr[i++] = NSOpenGLPFAAllowOfflineRenderers; - /* specify a profile if we're on Lion (10.7) or later. */ - if (lion_or_later) { - NSOpenGLPixelFormatAttribute profile = NSOpenGLProfileVersionLegacy; - if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_CORE) { - profile = NSOpenGLProfileVersion3_2Core; - } - attr[i++] = NSOpenGLPFAOpenGLProfile; - attr[i++] = profile; + NSOpenGLPixelFormatAttribute profile = NSOpenGLProfileVersionLegacy; + if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_CORE) { + profile = NSOpenGLProfileVersion3_2Core; } + attr[i++] = NSOpenGLPFAOpenGLProfile; + attr[i++] = profile; attr[i++] = NSOpenGLPFAColorSize; attr[i++] = SDL_BYTESPERPIXEL(display->current_mode.format)*8; @@ -288,20 +281,20 @@ Cocoa_GL_CreateContext(_THIS, SDL_Window * window) } if (_this->gl_config.share_with_current_context) { - share_context = (NSOpenGLContext*)SDL_GL_GetCurrentContext(); + share_context = (__bridge NSOpenGLContext*)SDL_GL_GetCurrentContext(); } context = [[SDLOpenGLContext alloc] initWithFormat:fmt shareContext:share_context]; - [fmt release]; - if (context == nil) { SDL_SetError("Failed creating OpenGL context"); return NULL; } - if ( Cocoa_GL_MakeCurrent(_this, window, context) < 0 ) { - Cocoa_GL_DeleteContext(_this, context); + sdlcontext = (SDL_GLContext)CFBridgingRetain(context); + + if ( Cocoa_GL_MakeCurrent(_this, window, (__bridge SDL_GLContext)context) < 0 ) { + Cocoa_GL_DeleteContext(_this, (__bridge SDL_GLContext)context); SDL_SetError("Failed making OpenGL context current"); return NULL; } @@ -315,27 +308,27 @@ Cocoa_GL_CreateContext(_THIS, SDL_Window * window) glGetStringFunc = (const GLubyte *(APIENTRY *)(GLenum)) SDL_GL_GetProcAddress("glGetString"); if (!glGetStringFunc) { - Cocoa_GL_DeleteContext(_this, context); + Cocoa_GL_DeleteContext(_this, (__bridge SDL_GLContext)context); SDL_SetError ("Failed getting OpenGL glGetString entry point"); return NULL; } glversion = (const char *)glGetStringFunc(GL_VERSION); if (glversion == NULL) { - Cocoa_GL_DeleteContext(_this, context); + Cocoa_GL_DeleteContext(_this, (__bridge SDL_GLContext)context); SDL_SetError ("Failed getting OpenGL context version"); return NULL; } if (SDL_sscanf(glversion, "%d.%d", &glversion_major, &glversion_minor) != 2) { - Cocoa_GL_DeleteContext(_this, context); + Cocoa_GL_DeleteContext(_this, (__bridge SDL_GLContext)context); SDL_SetError ("Failed parsing OpenGL context version"); return NULL; } if ((glversion_major < _this->gl_config.major_version) || ((glversion_major == _this->gl_config.major_version) && (glversion_minor < _this->gl_config.minor_version))) { - Cocoa_GL_DeleteContext(_this, context); + Cocoa_GL_DeleteContext(_this, (__bridge SDL_GLContext)context); SDL_SetError ("Failed creating OpenGL context at version requested"); return NULL; } @@ -346,7 +339,7 @@ Cocoa_GL_CreateContext(_THIS, SDL_Window * window) /*_this->gl_config.major_version = glversion_major;*/ /*_this->gl_config.minor_version = glversion_minor;*/ } - return context; + return sdlcontext; }} int @@ -354,7 +347,7 @@ Cocoa_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) { @autoreleasepool { if (context) { - SDLOpenGLContext *nscontext = (SDLOpenGLContext *)context; + SDLOpenGLContext *nscontext = (__bridge SDLOpenGLContext *)context; if ([nscontext window] != window) { [nscontext setWindow:window]; [nscontext updateIfNeeded]; @@ -369,17 +362,15 @@ Cocoa_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) void Cocoa_GL_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h) +{ @autoreleasepool { - SDL_WindowData *windata = (SDL_WindowData *) window->driverdata; - NSView *contentView = windata->sdlContentView; + SDL_WindowData *windata = (__bridge SDL_WindowData *) window->driverdata; + NSView *contentView = windata.sdlContentView; NSRect viewport = [contentView bounds]; if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { - /* This gives us the correct viewport for a Retina-enabled view, only - * supported on 10.7+. */ - if ([contentView respondsToSelector:@selector(convertRectToBacking:)]) { - viewport = [contentView convertRectToBacking:viewport]; - } + /* This gives us the correct viewport for a Retina-enabled view. */ + viewport = [contentView convertRectToBacking:viewport]; } if (w) { @@ -389,7 +380,7 @@ Cocoa_GL_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h) if (h) { *h = viewport.size.height; } -} +}} int Cocoa_GL_SetSwapInterval(_THIS, int interval) @@ -403,7 +394,7 @@ Cocoa_GL_SetSwapInterval(_THIS, int interval) return SDL_SetError("Late swap tearing currently unsupported"); } - nscontext = (NSOpenGLContext*)SDL_GL_GetCurrentContext(); + nscontext = (__bridge NSOpenGLContext*)SDL_GL_GetCurrentContext(); if (nscontext != nil) { value = interval; [nscontext setValues:&value forParameter:NSOpenGLCPSwapInterval]; @@ -423,7 +414,7 @@ Cocoa_GL_GetSwapInterval(_THIS) GLint value; int status = 0; - nscontext = (NSOpenGLContext*)SDL_GL_GetCurrentContext(); + nscontext = (__bridge NSOpenGLContext*)SDL_GL_GetCurrentContext(); if (nscontext != nil) { [nscontext getValues:&value forParameter:NSOpenGLCPSwapInterval]; status = (int)value; @@ -436,15 +427,15 @@ int Cocoa_GL_SwapWindow(_THIS, SDL_Window * window) { @autoreleasepool { - SDLOpenGLContext* nscontext = (SDLOpenGLContext*)SDL_GL_GetCurrentContext(); - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + SDLOpenGLContext* nscontext = (__bridge SDLOpenGLContext*)SDL_GL_GetCurrentContext(); + SDL_VideoData *videodata = (__bridge SDL_VideoData *) _this->driverdata; /* on 10.14 ("Mojave") and later, this deadlocks if two contexts in two threads try to swap at the same time, so put a mutex around it. */ - SDL_LockMutex(videodata->swaplock); + SDL_LockMutex(videodata.swaplock); [nscontext flushBuffer]; [nscontext updateIfNeeded]; - SDL_UnlockMutex(videodata->swaplock); + SDL_UnlockMutex(videodata.swaplock); return 0; }} @@ -452,10 +443,8 @@ void Cocoa_GL_DeleteContext(_THIS, SDL_GLContext context) { @autoreleasepool { - SDLOpenGLContext *nscontext = (SDLOpenGLContext *)context; - + SDLOpenGLContext *nscontext = (SDLOpenGLContext *)CFBridgingRelease(context); [nscontext setWindow:NULL]; - [nscontext release]; }} /* We still support OpenGL as long as Apple offers it, deprecated or not, so disable deprecation warnings about it. */ diff --git a/src/video/cocoa/SDL_cocoaopengles.m b/src/video/cocoa/SDL_cocoaopengles.m index 13102f8c0..63d013d8f 100644 --- a/src/video/cocoa/SDL_cocoaopengles.m +++ b/src/video/cocoa/SDL_cocoaopengles.m @@ -29,8 +29,8 @@ /* EGL implementation of SDL OpenGL support */ int -Cocoa_GLES_LoadLibrary(_THIS, const char *path) { - +Cocoa_GLES_LoadLibrary(_THIS, const char *path) +{ /* If the profile requested is not GL ES, switch over to WIN_GL functions */ if (_this->gl_config.profile_mask != SDL_GL_CONTEXT_PROFILE_ES) { #if SDL_VIDEO_OPENGL_CGL @@ -59,9 +59,10 @@ Cocoa_GLES_LoadLibrary(_THIS, const char *path) { SDL_GLContext Cocoa_GLES_CreateContext(_THIS, SDL_Window * window) +{ @autoreleasepool { SDL_GLContext context; - SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata; #if SDL_VIDEO_OPENGL_CGL if (_this->gl_config.profile_mask != SDL_GL_CONTEXT_PROFILE_ES) { @@ -85,25 +86,37 @@ Cocoa_GLES_CreateContext(_THIS, SDL_Window * window) } #endif - context = SDL_EGL_CreateContext(_this, data->egl_surface); + context = SDL_EGL_CreateContext(_this, data.egl_surface); return context; -} +}} void Cocoa_GLES_DeleteContext(_THIS, SDL_GLContext context) +{ @autoreleasepool { SDL_EGL_DeleteContext(_this, context); Cocoa_GLES_UnloadLibrary(_this); -} +}} -SDL_EGL_SwapWindow_impl(Cocoa) -SDL_EGL_MakeCurrent_impl(Cocoa) +int +Cocoa_GLES_SwapWindow(_THIS, SDL_Window * window) +{ @autoreleasepool +{ + return SDL_EGL_SwapBuffers(_this, ((__bridge SDL_WindowData *) window->driverdata).egl_surface); +}} + +int +Cocoa_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) +{ @autoreleasepool +{ + return SDL_EGL_MakeCurrent(_this, window ? ((__bridge SDL_WindowData *) window->driverdata).egl_surface : EGL_NO_SURFACE, context); +}} int Cocoa_GLES_SetupWindow(_THIS, SDL_Window * window) { /* The current context is lost in here; save it and reset it. */ - SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; + SDL_WindowData *windowdata = (__bridge SDL_WindowData *) window->driverdata; SDL_Window *current_win = SDL_GL_GetCurrentWindow(); SDL_GLContext current_ctx = SDL_GL_GetCurrentContext(); @@ -121,10 +134,10 @@ Cocoa_GLES_SetupWindow(_THIS, SDL_Window * window) } /* Create the GLES window surface */ - NSView* v = windowdata->nswindow.contentView; - windowdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType)[v layer]); + NSView* v = windowdata.nswindow.contentView; + windowdata.egl_surface = SDL_EGL_CreateSurface(_this, (__bridge NativeWindowType)[v layer]); - if (windowdata->egl_surface == EGL_NO_SURFACE) { + if (windowdata.egl_surface == EGL_NO_SURFACE) { return SDL_SetError("Could not create GLES window surface"); } diff --git a/src/video/cocoa/SDL_cocoashape.m b/src/video/cocoa/SDL_cocoashape.m index 1176036ac..2fa5cab0f 100644 --- a/src/video/cocoa/SDL_cocoashape.m +++ b/src/video/cocoa/SDL_cocoashape.m @@ -29,11 +29,12 @@ SDL_WindowShaper* Cocoa_CreateShaper(SDL_Window* window) +{ @autoreleasepool { - SDL_WindowData* windata = (SDL_WindowData*)window->driverdata; - [windata->nswindow setOpaque:NO]; + SDL_WindowData* windata = (__bridge SDL_WindowData*)window->driverdata; + [windata.nswindow setOpaque:NO]; - [windata->nswindow setStyleMask:NSWindowStyleMaskBorderless]; + [windata.nswindow setStyleMask:NSWindowStyleMaskBorderless]; SDL_WindowShaper* result = (SDL_WindowShaper *)SDL_malloc(sizeof(SDL_WindowShaper)); result->window = window; @@ -44,14 +45,14 @@ Cocoa_CreateShaper(SDL_Window* window) SDL_ShapeData* data = (SDL_ShapeData *)SDL_malloc(sizeof(SDL_ShapeData)); result->driverdata = data; - data->context = [windata->nswindow graphicsContext]; + data->context = [windata.nswindow graphicsContext]; data->saved = SDL_FALSE; data->shape = NULL; int resized_properly = Cocoa_ResizeWindowShape(window); SDL_assert(resized_properly == 0); return result; -} +}} typedef struct { NSView* view; @@ -74,7 +75,7 @@ Cocoa_SetWindowShape(SDL_WindowShaper *shaper, SDL_Surface *shape, SDL_WindowSha { @autoreleasepool { SDL_ShapeData* data = (SDL_ShapeData*)shaper->driverdata; - SDL_WindowData* windata = (SDL_WindowData*)shaper->window->driverdata; + SDL_WindowData* windata = (__bridge SDL_WindowData*)shaper->window->driverdata; SDL_CocoaClosure closure; if(data->saved == SDL_TRUE) { [data->context restoreGraphicsState]; @@ -86,10 +87,10 @@ Cocoa_SetWindowShape(SDL_WindowShaper *shaper, SDL_Surface *shape, SDL_WindowSha [NSGraphicsContext setCurrentContext:data->context]; [[NSColor clearColor] set]; - NSRectFill([windata->sdlContentView frame]); + NSRectFill([windata.sdlContentView frame]); data->shape = SDL_CalculateShapeTree(*shape_mode,shape); - closure.view = windata->sdlContentView; + closure.view = windata.sdlContentView; closure.path = [NSBezierPath bezierPath]; closure.window = shaper->window; SDL_TraverseShapeTree(data->shape,&ConvertRects,&closure); diff --git a/src/video/cocoa/SDL_cocoavideo.h b/src/video/cocoa/SDL_cocoavideo.h index af0abe5cc..4de8511a3 100644 --- a/src/video/cocoa/SDL_cocoavideo.h +++ b/src/video/cocoa/SDL_cocoavideo.h @@ -97,18 +97,15 @@ DECLARE_ALERT_STYLE(Critical); @class SDLTranslatorResponder; -typedef struct SDL_VideoData -{ - int allow_spaces; - unsigned int modifierFlags; - void *key_layout; - SDLTranslatorResponder *fieldEdit; - NSInteger clipboard_count; - Uint32 screensaver_activity; - BOOL screensaver_use_iopm; - IOPMAssertionID screensaver_assertion; - SDL_mutex *swaplock; -} SDL_VideoData; +@interface SDL_VideoData : NSObject + @property (nonatomic) int allow_spaces; + @property (nonatomic) unsigned int modifierFlags; + @property (nonatomic) void *key_layout; + @property (nonatomic) SDLTranslatorResponder *fieldEdit; + @property (nonatomic) NSInteger clipboard_count; + @property (nonatomic) IOPMAssertionID screensaver_assertion; + @property (nonatomic) SDL_mutex *swaplock; +@end /* Utility functions */ extern NSImage * Cocoa_CreateImage(SDL_Surface * surface); diff --git a/src/video/cocoa/SDL_cocoavideo.m b/src/video/cocoa/SDL_cocoavideo.m index 231b2de5c..1df31f648 100644 --- a/src/video/cocoa/SDL_cocoavideo.m +++ b/src/video/cocoa/SDL_cocoavideo.m @@ -22,6 +22,10 @@ #if SDL_VIDEO_DRIVER_COCOA +#if !__has_feature(objc_arc) +#error SDL must be built with Objective-C ARC (automatic reference counting) enabled +#endif + #include "SDL.h" #include "SDL_endian.h" #include "SDL_cocoavideo.h" @@ -29,6 +33,10 @@ #include "SDL_cocoavulkan.h" #include "SDL_cocoametalview.h" +@implementation SDL_VideoData + +@end + /* Initialization/Query functions */ static int Cocoa_VideoInit(_THIS); static void Cocoa_VideoQuit(_THIS); @@ -37,16 +45,18 @@ static void Cocoa_VideoQuit(_THIS); static void Cocoa_DeleteDevice(SDL_VideoDevice * device) +{ @autoreleasepool { if (device->wakeup_lock) { SDL_DestroyMutex(device->wakeup_lock); } - SDL_free(device->driverdata); + CFBridgingRelease(device->driverdata); SDL_free(device); -} +}} static SDL_VideoDevice * Cocoa_CreateDevice(int devindex) +{ @autoreleasepool { SDL_VideoDevice *device; SDL_VideoData *data; @@ -56,16 +66,16 @@ Cocoa_CreateDevice(int devindex) /* Initialize all variables that we clean on shutdown */ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); if (device) { - data = (struct SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); + data = [[SDL_VideoData alloc] init]; } else { - data = NULL; + data = nil; } if (!data) { SDL_OutOfMemory(); SDL_free(device); return NULL; } - device->driverdata = data; + device->driverdata = (void *)CFBridgingRetain(data); device->wakeup_lock = SDL_CreateMutex(); /* Set the function pointers */ @@ -103,6 +113,7 @@ Cocoa_CreateDevice(int devindex) device->SetWindowGammaRamp = Cocoa_SetWindowGammaRamp; device->GetWindowGammaRamp = Cocoa_GetWindowGammaRamp; device->GetWindowICCProfile = Cocoa_GetWindowICCProfile; + device->GetWindowDisplayIndex = Cocoa_GetWindowDisplayIndex; device->SetWindowMouseRect = Cocoa_SetWindowMouseRect; device->SetWindowMouseGrab = Cocoa_SetWindowMouseGrab; device->SetWindowKeyboardGrab = Cocoa_SetWindowKeyboardGrab; @@ -165,7 +176,7 @@ Cocoa_CreateDevice(int devindex) device->free = Cocoa_DeleteDevice; return device; -} +}} VideoBootStrap COCOA_bootstrap = { "cocoa", "SDL Cocoa video driver", @@ -175,8 +186,9 @@ VideoBootStrap COCOA_bootstrap = { int Cocoa_VideoInit(_THIS) +{ @autoreleasepool { - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata; Cocoa_InitModes(_this); Cocoa_InitKeyboard(_this); @@ -184,29 +196,27 @@ Cocoa_VideoInit(_THIS) return -1; } - data->allow_spaces = ((floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) && SDL_GetHintBoolean(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, SDL_TRUE)); + data.allow_spaces = SDL_GetHintBoolean(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, SDL_TRUE); - /* The IOPM assertion API can disable the screensaver as of 10.7. */ - data->screensaver_use_iopm = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6; - - data->swaplock = SDL_CreateMutex(); - if (!data->swaplock) { + data.swaplock = SDL_CreateMutex(); + if (!data.swaplock) { return -1; } return 0; -} +}} void Cocoa_VideoQuit(_THIS) +{ @autoreleasepool { - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata; Cocoa_QuitModes(_this); Cocoa_QuitKeyboard(_this); Cocoa_QuitMouse(_this); - SDL_DestroyMutex(data->swaplock); - data->swaplock = NULL; -} + SDL_DestroyMutex(data.swaplock); + data.swaplock = NULL; +}} /* This function assumes that it's called from within an autorelease pool */ NSImage * @@ -223,7 +233,7 @@ Cocoa_CreateImage(SDL_Surface * surface) return nil; } - imgrep = [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL + imgrep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL pixelsWide: converted->w pixelsHigh: converted->h bitsPerSample: 8 @@ -232,7 +242,7 @@ Cocoa_CreateImage(SDL_Surface * surface) isPlanar: NO colorSpaceName: NSDeviceRGBColorSpace bytesPerRow: converted->pitch - bitsPerPixel: converted->format->BitsPerPixel] autorelease]; + bitsPerPixel: converted->format->BitsPerPixel]; if (imgrep == nil) { SDL_FreeSurface(converted); return nil; @@ -252,7 +262,7 @@ Cocoa_CreateImage(SDL_Surface * surface) pixels += 4; } - img = [[[NSImage alloc] initWithSize: NSMakeSize(surface->w, surface->h)] autorelease]; + img = [[NSImage alloc] initWithSize: NSMakeSize(surface->w, surface->h)]; if (img != nil) { [img addRepresentation: imgrep]; } @@ -269,11 +279,16 @@ Cocoa_CreateImage(SDL_Surface * surface) * versions remain identical! */ -void SDL_NSLog(const char *text) +void SDL_NSLog(const char *prefix, const char *text) { @autoreleasepool { - NSString *str = [NSString stringWithUTF8String:text]; - NSLog(@"%@", str); + NSString *nsText = [NSString stringWithUTF8String:text]; + if (prefix) { + NSString *nsPrefix = [NSString stringWithUTF8String:prefix]; + NSLog(@"%@: %@", nsPrefix, nsText); + } else { + NSLog(@"%@", nsText); + } } } diff --git a/src/video/cocoa/SDL_cocoavulkan.m b/src/video/cocoa/SDL_cocoavulkan.m index 20c83d47d..02817f8f1 100644 --- a/src/video/cocoa/SDL_cocoavulkan.m +++ b/src/video/cocoa/SDL_cocoavulkan.m @@ -53,6 +53,7 @@ int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path) VkExtensionProperties *extensions = NULL; Uint32 extensionCount = 0; SDL_bool hasSurfaceExtension = SDL_FALSE; + SDL_bool hasMetalSurfaceExtension = SDL_FALSE; SDL_bool hasMacOSSurfaceExtension = SDL_FALSE; PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL; @@ -130,6 +131,8 @@ int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path) for (Uint32 i = 0; i < extensionCount; i++) { if (SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { hasSurfaceExtension = SDL_TRUE; + } else if (SDL_strcmp(VK_EXT_METAL_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { + hasMetalSurfaceExtension = SDL_TRUE; } else if (SDL_strcmp(VK_MVK_MACOS_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { hasMacOSSurfaceExtension = SDL_TRUE; } @@ -139,9 +142,10 @@ int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path) SDL_SetError("Installed Vulkan Portability library doesn't implement the " VK_KHR_SURFACE_EXTENSION_NAME " extension"); goto fail; - } else if (!hasMacOSSurfaceExtension) { + } else if (!hasMetalSurfaceExtension && !hasMacOSSurfaceExtension) { SDL_SetError("Installed Vulkan Portability library doesn't implement the " - VK_MVK_MACOS_SURFACE_EXTENSION_NAME "extension"); + VK_EXT_METAL_SURFACE_EXTENSION_NAME " or " + VK_MVK_MACOS_SURFACE_EXTENSION_NAME " extensions"); goto fail; } return 0; @@ -168,7 +172,7 @@ SDL_bool Cocoa_Vulkan_GetInstanceExtensions(_THIS, const char **names) { static const char *const extensionsForCocoa[] = { - VK_KHR_SURFACE_EXTENSION_NAME, VK_MVK_MACOS_SURFACE_EXTENSION_NAME + VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_METAL_SURFACE_EXTENSION_NAME }; if (!_this->vulkan_config.loader_handle) { SDL_SetError("Vulkan is not loaded"); @@ -186,11 +190,14 @@ SDL_bool Cocoa_Vulkan_CreateSurface(_THIS, { PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr; + PFN_vkCreateMetalSurfaceEXT vkCreateMetalSurfaceEXT = + (PFN_vkCreateMetalSurfaceEXT)vkGetInstanceProcAddr( + (VkInstance)instance, + "vkCreateMetalSurfaceEXT"); PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK = (PFN_vkCreateMacOSSurfaceMVK)vkGetInstanceProcAddr( (VkInstance)instance, "vkCreateMacOSSurfaceMVK"); - VkMacOSSurfaceCreateInfoMVK createInfo = {}; VkResult result; SDL_MetalView metalview; @@ -199,9 +206,10 @@ SDL_bool Cocoa_Vulkan_CreateSurface(_THIS, return SDL_FALSE; } - if (!vkCreateMacOSSurfaceMVK) { - SDL_SetError(VK_MVK_MACOS_SURFACE_EXTENSION_NAME - " extension is not enabled in the Vulkan instance."); + if (!vkCreateMetalSurfaceEXT && !vkCreateMacOSSurfaceMVK) { + SDL_SetError(VK_EXT_METAL_SURFACE_EXTENSION_NAME " or " + VK_MVK_MACOS_SURFACE_EXTENSION_NAME + " extensions are not enabled in the Vulkan instance."); return SDL_FALSE; } @@ -210,17 +218,34 @@ SDL_bool Cocoa_Vulkan_CreateSurface(_THIS, return SDL_FALSE; } - createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; - createInfo.pNext = NULL; - createInfo.flags = 0; - createInfo.pView = (const void *)metalview; - result = vkCreateMacOSSurfaceMVK(instance, &createInfo, - NULL, surface); - if (result != VK_SUCCESS) { - Cocoa_Metal_DestroyView(_this, metalview); - SDL_SetError("vkCreateMacOSSurfaceMVK failed: %s", - SDL_Vulkan_GetResultString(result)); - return SDL_FALSE; + if (vkCreateMetalSurfaceEXT) { + VkMetalSurfaceCreateInfoEXT createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.pLayer = (__bridge const CAMetalLayer *) + Cocoa_Metal_GetLayer(_this, metalview); + result = vkCreateMetalSurfaceEXT(instance, &createInfo, NULL, surface); + if (result != VK_SUCCESS) { + Cocoa_Metal_DestroyView(_this, metalview); + SDL_SetError("vkCreateMetalSurfaceEXT failed: %s", + SDL_Vulkan_GetResultString(result)); + return SDL_FALSE; + } + } else { + VkMacOSSurfaceCreateInfoMVK createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.pView = (const void *)metalview; + result = vkCreateMacOSSurfaceMVK(instance, &createInfo, + NULL, surface); + if (result != VK_SUCCESS) { + Cocoa_Metal_DestroyView(_this, metalview); + SDL_SetError("vkCreateMacOSSurfaceMVK failed: %s", + SDL_Vulkan_GetResultString(result)); + return SDL_FALSE; + } } /* Unfortunately there's no SDL_Vulkan_DestroySurface function we can call diff --git a/src/video/cocoa/SDL_cocoawindow.h b/src/video/cocoa/SDL_cocoawindow.h index a42d9c87b..61324550a 100644 --- a/src/video/cocoa/SDL_cocoawindow.h +++ b/src/video/cocoa/SDL_cocoawindow.h @@ -29,7 +29,7 @@ #include "../SDL_egl_c.h" #endif -typedef struct SDL_WindowData SDL_WindowData; +@class SDL_WindowData; typedef enum { @@ -40,7 +40,10 @@ typedef enum } PendingWindowOperation; @interface Cocoa_WindowListener : NSResponder { - SDL_WindowData *_data; + /* SDL_WindowData owns this Listener and has a strong reference to it. + * To avoid reference cycles, we could have either a weak or an + * unretained ref to the WindowData. */ + __weak SDL_WindowData *_data; BOOL observingVisible; BOOL wasCtrlLeft; BOOL wasVisible; @@ -114,22 +117,22 @@ typedef enum /* *INDENT-ON* */ @class SDLOpenGLContext; +@class SDL_VideoData; -struct SDL_WindowData -{ - SDL_Window *window; - NSWindow *nswindow; - NSView *sdlContentView; - NSMutableArray *nscontexts; - SDL_bool created; - SDL_bool inWindowFullscreenTransition; - NSInteger flash_request; - Cocoa_WindowListener *listener; - struct SDL_VideoData *videodata; +@interface SDL_WindowData : NSObject + @property (nonatomic) SDL_Window *window; + @property (nonatomic) NSWindow *nswindow; + @property (nonatomic) NSView *sdlContentView; + @property (nonatomic) NSMutableArray *nscontexts; + @property (nonatomic) SDL_bool created; + @property (nonatomic) SDL_bool inWindowFullscreenTransition; + @property (nonatomic) NSInteger flash_request; + @property (nonatomic) Cocoa_WindowListener *listener; + @property (nonatomic) SDL_VideoData *videodata; #if SDL_VIDEO_OPENGL_EGL - EGLSurface egl_surface; + @property (nonatomic) EGLSurface egl_surface; #endif -}; +@end extern int Cocoa_CreateWindow(_THIS, SDL_Window * window); extern int Cocoa_CreateWindowFrom(_THIS, SDL_Window * window, @@ -153,6 +156,7 @@ extern void Cocoa_SetWindowAlwaysOnTop(_THIS, SDL_Window * window, SDL_bool on_t extern void Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern int Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); extern void* Cocoa_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size); +extern int Cocoa_GetWindowDisplayIndex(_THIS, SDL_Window * window); extern int Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp); extern void Cocoa_SetWindowMouseRect(_THIS, SDL_Window * window); extern void Cocoa_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed); diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m index bca8eb4dd..44e91440c 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -62,6 +62,10 @@ #define NSAppKitVersionNumber10_14 1671 #endif +@implementation SDL_WindowData + +@end + @interface NSWindow (SDL) #if MAC_OS_X_VERSION_MAX_ALLOWED < 101000 /* Added in the 10.10 SDK */ @property (readonly) NSRect contentLayoutRect; @@ -227,7 +231,7 @@ /* !!! FIXME: is there a better way to do this? */ if (_this) { for (sdlwindow = _this->windows; sdlwindow; sdlwindow = sdlwindow->next) { - NSWindow *nswindow = ((SDL_WindowData *) sdlwindow->driverdata)->nswindow; + NSWindow *nswindow = ((__bridge SDL_WindowData *) sdlwindow->driverdata).nswindow; if (nswindow == self) { break; } @@ -250,7 +254,7 @@ static void ConvertNSRect(NSScreen *screen, BOOL fullscreen, NSRect *r) static void ScheduleContextUpdates(SDL_WindowData *data) { - if (!data || !data->nscontexts) { + if (!data || !data.nscontexts) { return; } @@ -261,7 +265,7 @@ ScheduleContextUpdates(SDL_WindowData *data) #endif NSOpenGLContext *currentContext = [NSOpenGLContext currentContext]; - NSMutableArray *contexts = data->nscontexts; + NSMutableArray *contexts = data.nscontexts; @synchronized (contexts) { for (SDLOpenGLContext *context in contexts) { if (context == currentContext) { @@ -316,19 +320,19 @@ GetWindowStyle(SDL_Window * window) static SDL_bool SetWindowStyle(SDL_Window * window, NSUInteger style) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - NSWindow *nswindow = data->nswindow; + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; + NSWindow *nswindow = data.nswindow; /* The view responder chain gets messed with during setStyleMask */ - if ([data->sdlContentView nextResponder] == data->listener) { - [data->sdlContentView setNextResponder:nil]; + if ([data.sdlContentView nextResponder] == data.listener) { + [data.sdlContentView setNextResponder:nil]; } [nswindow setStyleMask:style]; /* The view responder chain gets messed with during setStyleMask */ - if ([data->sdlContentView nextResponder] != data->listener) { - [data->sdlContentView setNextResponder:data->listener]; + if ([data.sdlContentView nextResponder] != data.listener) { + [data.sdlContentView setNextResponder:data.listener]; } return SDL_TRUE; @@ -337,9 +341,9 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) static SDL_bool ShouldAdjustCoordinatesForGrab(SDL_Window * window) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; - if (!data || [data->listener isMovingOrFocusClickPending]) { + if (!data || [data.listener isMovingOrFocusClickPending]) { return SDL_FALSE; } @@ -396,10 +400,10 @@ AdjustCoordinatesForGrab(SDL_Window * window, int x, int y, CGPoint *adjusted) static void Cocoa_UpdateClipCursor(SDL_Window * window) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_13_2) { - NSWindow *nswindow = data->nswindow; + NSWindow *nswindow = data.nswindow; SDL_Rect mouse_rect; SDL_zero(mouse_rect); @@ -453,8 +457,8 @@ Cocoa_UpdateClipCursor(SDL_Window * window) - (void)listen:(SDL_WindowData *)data { NSNotificationCenter *center; - NSWindow *window = data->nswindow; - NSView *view = data->sdlContentView; + NSWindow *window = data.nswindow; + NSView *view = data.sdlContentView; _data = data; observingVisible = YES; @@ -515,12 +519,12 @@ Cocoa_UpdateClipCursor(SDL_Window * window) return; } - if (object == _data->nswindow && [keyPath isEqualToString:@"visible"]) { + if (object == _data.nswindow && [keyPath isEqualToString:@"visible"]) { int newVisibility = [[change objectForKey:@"new"] intValue]; if (newVisibility) { - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_SHOWN, 0, 0); + SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_SHOWN, 0, 0); } else { - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0); + SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_HIDDEN, 0, 0); } } } @@ -528,18 +532,18 @@ Cocoa_UpdateClipCursor(SDL_Window * window) -(void) pauseVisibleObservation { observingVisible = NO; - wasVisible = [_data->nswindow isVisible]; + wasVisible = [_data.nswindow isVisible]; } -(void) resumeVisibleObservation { - BOOL isVisible = [_data->nswindow isVisible]; + BOOL isVisible = [_data.nswindow isVisible]; observingVisible = YES; if (wasVisible != isVisible) { if (isVisible) { - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_SHOWN, 0, 0); + SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_SHOWN, 0, 0); } else { - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0); + SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_HIDDEN, 0, 0); } wasVisible = isVisible; @@ -548,11 +552,11 @@ Cocoa_UpdateClipCursor(SDL_Window * window) -(BOOL) setFullscreenSpace:(BOOL) state { - SDL_Window *window = _data->window; - NSWindow *nswindow = _data->nswindow; - SDL_VideoData *videodata = ((SDL_WindowData *) window->driverdata)->videodata; + SDL_Window *window = _data.window; + NSWindow *nswindow = _data.nswindow; + SDL_VideoData *videodata = ((__bridge SDL_WindowData *) window->driverdata).videodata; - if (!videodata->allow_spaces) { + if (!videodata.allow_spaces) { return NO; /* Spaces are forcibly disabled. */ } else if (state && ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP)) { return NO; /* we only allow you to make a Space on FULLSCREEN_DESKTOP windows. */ @@ -596,7 +600,7 @@ Cocoa_UpdateClipCursor(SDL_Window * window) - (void)close { NSNotificationCenter *center; - NSWindow *window = _data->nswindow; + NSWindow *window = _data.nswindow; NSView *view = [window contentView]; center = [NSNotificationCenter defaultCenter]; @@ -678,15 +682,15 @@ Cocoa_UpdateClipCursor(SDL_Window * window) mouse->WarpMouseGlobal(pendingWindowWarpX, pendingWindowWarpY); pendingWindowWarpX = pendingWindowWarpY = INT_MAX; } - if (mouse->relative_mode && !mouse->relative_mode_warp && mouse->focus == _data->window) { + if (mouse->relative_mode && !mouse->relative_mode_warp && mouse->focus == _data.window) { /* Move the cursor to the nearest point in the window */ { int x, y; CGPoint cgpoint; SDL_GetMouseState(&x, &y); - cgpoint.x = _data->window->x + x; - cgpoint.y = _data->window->y + y; + cgpoint.x = _data.window->x + x; + cgpoint.y = _data.window->y + y; Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y); @@ -696,25 +700,25 @@ Cocoa_UpdateClipCursor(SDL_Window * window) mouse->SetRelativeMouseMode(SDL_TRUE); } else { - Cocoa_UpdateClipCursor(_data->window); + Cocoa_UpdateClipCursor(_data.window); } } } - (BOOL)windowShouldClose:(id)sender { - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_CLOSE, 0, 0); + SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_CLOSE, 0, 0); return NO; } - (void)windowDidExpose:(NSNotification *)aNotification { - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_EXPOSED, 0, 0); + SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_EXPOSED, 0, 0); } - (void)windowWillMove:(NSNotification *)aNotification { - if ([_data->nswindow isKindOfClass:[SDLWindow class]]) { + if ([_data.nswindow isKindOfClass:[SDLWindow class]]) { pendingWindowWarpX = pendingWindowWarpY = INT_MAX; isMoving = YES; } @@ -723,8 +727,8 @@ Cocoa_UpdateClipCursor(SDL_Window * window) - (void)windowDidMove:(NSNotification *)aNotification { int x, y; - SDL_Window *window = _data->window; - NSWindow *nswindow = _data->nswindow; + SDL_Window *window = _data.window; + NSWindow *nswindow = _data.nswindow; BOOL fullscreen = window->flags & FULLSCREEN_MASK; NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]]; ConvertNSRect([nswindow screen], fullscreen, &rect); @@ -764,8 +768,8 @@ Cocoa_UpdateClipCursor(SDL_Window * window) return; } - SDL_Window *window = _data->window; - NSWindow *nswindow = _data->nswindow; + SDL_Window *window = _data.window; + NSWindow *nswindow = _data.nswindow; int x, y, w, h; NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]]; ConvertNSRect([nswindow screen], (window->flags & FULLSCREEN_MASK), &rect); @@ -799,17 +803,17 @@ Cocoa_UpdateClipCursor(SDL_Window * window) focusClickPending = 0; [self onMovingOrFocusClickPendingStateCleared]; } - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_MINIMIZED, 0, 0); + SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_MINIMIZED, 0, 0); } - (void)windowDidDeminiaturize:(NSNotification *)aNotification { - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_RESTORED, 0, 0); + SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_RESTORED, 0, 0); } - (void)windowDidBecomeKey:(NSNotification *)aNotification { - SDL_Window *window = _data->window; + SDL_Window *window = _data.window; SDL_Mouse *mouse = SDL_GetMouse(); /* We're going to get keyboard events, since we're key. */ @@ -825,7 +829,7 @@ Cocoa_UpdateClipCursor(SDL_Window * window) NSPoint point; int x, y; - point = [_data->nswindow mouseLocationOutsideOfEventStream]; + point = [_data.nswindow mouseLocationOutsideOfEventStream]; x = (int)point.x; y = (int)(window->h - point.y); @@ -835,14 +839,14 @@ Cocoa_UpdateClipCursor(SDL_Window * window) } /* Check to see if someone updated the clipboard */ - Cocoa_CheckClipboardUpdate(_data->videodata); + Cocoa_CheckClipboardUpdate(_data.videodata); if ((isFullscreenSpace) && ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP)) { [NSMenu setMenuBarVisible:NO]; } const unsigned int newflags = [NSEvent modifierFlags] & NSEventModifierFlagCapsLock; - _data->videodata->modifierFlags = (_data->videodata->modifierFlags & ~NSEventModifierFlagCapsLock) | newflags; + _data.videodata.modifierFlags = (_data.videodata.modifierFlags & ~NSEventModifierFlagCapsLock) | newflags; SDL_ToggleModState(KMOD_CAPS, newflags != 0); } @@ -854,12 +858,12 @@ Cocoa_UpdateClipCursor(SDL_Window * window) } /* Some other window will get mouse events, since we're not key. */ - if (SDL_GetMouseFocus() == _data->window) { + if (SDL_GetMouseFocus() == _data.window) { SDL_SetMouseFocus(NULL); } /* Some other window will get keyboard events, since we're not key. */ - if (SDL_GetKeyboardFocus() == _data->window) { + if (SDL_GetKeyboardFocus() == _data.window) { SDL_SetKeyboardFocus(NULL); } @@ -876,22 +880,22 @@ Cocoa_UpdateClipCursor(SDL_Window * window) return; } - if ([oldscale doubleValue] != [_data->nswindow backingScaleFactor]) { + if ([oldscale doubleValue] != [_data.nswindow backingScaleFactor]) { /* Force a resize event when the backing scale factor changes. */ - _data->window->w = 0; - _data->window->h = 0; + _data.window->w = 0; + _data.window->h = 0; [self windowDidResize:aNotification]; } } - (void)windowDidChangeScreenProfile:(NSNotification *)aNotification { - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_ICCPROF_CHANGED, 0, 0); + SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_ICCPROF_CHANGED, 0, 0); } - (void)windowWillEnterFullScreen:(NSNotification *)aNotification { - SDL_Window *window = _data->window; + SDL_Window *window = _data.window; SetWindowStyle(window, (NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable|NSWindowStyleMaskResizable)); @@ -901,7 +905,7 @@ Cocoa_UpdateClipCursor(SDL_Window * window) - (void)windowDidFailToEnterFullScreen:(NSNotification *)aNotification { - SDL_Window *window = _data->window; + SDL_Window *window = _data.window; if (window->is_destroying) { return; @@ -917,9 +921,9 @@ Cocoa_UpdateClipCursor(SDL_Window * window) - (void)windowDidEnterFullScreen:(NSNotification *)aNotification { - SDL_Window *window = _data->window; - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - NSWindow *nswindow = data->nswindow; + SDL_Window *window = _data.window; + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; + NSWindow *nswindow = data.nswindow; inFullscreenTransition = NO; @@ -949,7 +953,7 @@ Cocoa_UpdateClipCursor(SDL_Window * window) - (void)windowWillExitFullScreen:(NSNotification *)aNotification { - SDL_Window *window = _data->window; + SDL_Window *window = _data.window; isFullscreenSpace = NO; inFullscreenTransition = YES; @@ -967,7 +971,7 @@ Cocoa_UpdateClipCursor(SDL_Window * window) - (void)windowDidFailToExitFullScreen:(NSNotification *)aNotification { - SDL_Window *window = _data->window; + SDL_Window *window = _data.window; if (window->is_destroying) { return; @@ -983,8 +987,8 @@ Cocoa_UpdateClipCursor(SDL_Window * window) - (void)windowDidExitFullScreen:(NSNotification *)aNotification { - SDL_Window *window = _data->window; - NSWindow *nswindow = _data->nswindow; + SDL_Window *window = _data.window; + NSWindow *nswindow = _data.nswindow; NSButton *button = nil; inFullscreenTransition = NO; @@ -1077,7 +1081,7 @@ Cocoa_UpdateClipCursor(SDL_Window * window) -(NSApplicationPresentationOptions)window:(NSWindow *)window willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)proposedOptions { - if ((_data->window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) { + if ((_data.window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) { return NSApplicationPresentationFullScreen | NSApplicationPresentationHideDock | NSApplicationPresentationHideMenuBar; } else { return proposedOptions; @@ -1127,16 +1131,16 @@ Cocoa_UpdateClipCursor(SDL_Window * window) - (BOOL)processHitTest:(NSEvent *)theEvent { - SDL_assert(isDragAreaRunning == [_data->nswindow isMovableByWindowBackground]); + SDL_assert(isDragAreaRunning == [_data.nswindow isMovableByWindowBackground]); - if (_data->window->hit_test) { /* if no hit-test, skip this. */ + if (_data.window->hit_test) { /* if no hit-test, skip this. */ const NSPoint location = [theEvent locationInWindow]; - const SDL_Point point = { (int) location.x, _data->window->h - (((int) location.y)-1) }; - const SDL_HitTestResult rc = _data->window->hit_test(_data->window, &point, _data->window->hit_test_data); + const SDL_Point point = { (int) location.x, _data.window->h - (((int) location.y)-1) }; + const SDL_HitTestResult rc = _data.window->hit_test(_data.window, &point, _data.window->hit_test_data); if (rc == SDL_HITTEST_DRAGGABLE) { if (!isDragAreaRunning) { isDragAreaRunning = YES; - [_data->nswindow setMovableByWindowBackground:YES]; + [_data.nswindow setMovableByWindowBackground:YES]; } return YES; /* dragging! */ } @@ -1144,7 +1148,7 @@ Cocoa_UpdateClipCursor(SDL_Window * window) if (isDragAreaRunning) { isDragAreaRunning = NO; - [_data->nswindow setMovableByWindowBackground:NO]; + [_data.nswindow setMovableByWindowBackground:NO]; return YES; /* was dragging, drop event. */ } @@ -1164,7 +1168,7 @@ Cocoa_SendMouseButtonClicks(SDL_Mouse * mouse, NSEvent *theEvent, SDL_Window * w // the position in the currently-focused window. We don't (currently) send a mousemove // event for the background window, this just makes sure the button is reported at the // correct position in its own event. - if ( focus && ([theEvent window] == ((SDL_WindowData *) focus->driverdata)->nswindow) ) { + if ( focus && ([theEvent window] == ((__bridge SDL_WindowData *) focus->driverdata).nswindow) ) { rc = SDL_SendMouseButtonClicks(window, mouseID, state, button, clicks); } else { const int orig_x = mouse->x; @@ -1198,7 +1202,7 @@ Cocoa_SendMouseButtonClicks(SDL_Mouse * mouse, NSEvent *theEvent, SDL_Window * w } if ([self processHitTest:theEvent]) { - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0); + SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_HIT_TEST, 0, 0); return; /* dragging, drop event. */ } @@ -1224,7 +1228,7 @@ Cocoa_SendMouseButtonClicks(SDL_Mouse * mouse, NSEvent *theEvent, SDL_Window * w break; } - Cocoa_SendMouseButtonClicks(mouse, theEvent, _data->window, SDL_PRESSED, button); + Cocoa_SendMouseButtonClicks(mouse, theEvent, _data.window, SDL_PRESSED, button); } - (void)rightMouseDown:(NSEvent *)theEvent @@ -1247,7 +1251,7 @@ Cocoa_SendMouseButtonClicks(SDL_Mouse * mouse, NSEvent *theEvent, SDL_Window * w int button; if ([self processHitTest:theEvent]) { - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0); + SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_HIT_TEST, 0, 0); return; /* stopped dragging, drop event. */ } @@ -1271,7 +1275,7 @@ Cocoa_SendMouseButtonClicks(SDL_Mouse * mouse, NSEvent *theEvent, SDL_Window * w break; } - Cocoa_SendMouseButtonClicks(mouse, theEvent, _data->window, SDL_RELEASED, button); + Cocoa_SendMouseButtonClicks(mouse, theEvent, _data.window, SDL_RELEASED, button); } - (void)rightMouseUp:(NSEvent *)theEvent @@ -1292,7 +1296,7 @@ Cocoa_SendMouseButtonClicks(SDL_Mouse * mouse, NSEvent *theEvent, SDL_Window * w } const SDL_MouseID mouseID = mouse->mouseID; - SDL_Window *window = _data->window; + SDL_Window *window = _data.window; NSPoint point; int x, y; @@ -1341,7 +1345,7 @@ Cocoa_SendMouseButtonClicks(SDL_Mouse * mouse, NSEvent *theEvent, SDL_Window * w - (void)scrollWheel:(NSEvent *)theEvent { - Cocoa_HandleMouseWheel(_data->window, theEvent); + Cocoa_HandleMouseWheel(_data.window, theEvent); } - (void)touchesBeganWithEvent:(NSEvent *) theEvent @@ -1531,7 +1535,7 @@ Cocoa_SendMouseButtonClicks(SDL_Mouse * mouse, NSEvent *theEvent, SDL_Window * w white until the app is ready to draw. In practice on modern macOS, this only gets called for window creation and other extraordinary events. */ self.layer.backgroundColor = CGColorGetConstantColor(kCGColorBlack); - ScheduleContextUpdates((SDL_WindowData *) _sdlWindow->driverdata); + ScheduleContextUpdates((__bridge SDL_WindowData *) _sdlWindow->driverdata); SDL_SendWindowEvent(_sdlWindow, SDL_WINDOWEVENT_EXPOSED, 0, 0); } @@ -1555,7 +1559,7 @@ Cocoa_SendMouseButtonClicks(SDL_Mouse * mouse, NSEvent *theEvent, SDL_Window * w if (mouse->cursor_shown && mouse->cur_cursor && !mouse->relative_mode) { [self addCursorRect:[self bounds] - cursor:mouse->cur_cursor->driverdata]; + cursor:(__bridge NSCursor *)mouse->cur_cursor->driverdata]; } else { [self addCursorRect:[self bounds] cursor:[NSCursor invisibleCursor]]; @@ -1576,23 +1580,23 @@ static int SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, NSView *nsview, SDL_bool created) { @autoreleasepool { - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *videodata = (__bridge SDL_VideoData *) _this->driverdata; SDL_WindowData *data; /* Allocate the window data */ - window->driverdata = data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data)); + data = [[SDL_WindowData alloc] init]; if (!data) { return SDL_OutOfMemory(); } - data->window = window; - data->nswindow = nswindow; - data->created = created; - data->videodata = videodata; - data->nscontexts = [[NSMutableArray alloc] init]; - data->sdlContentView = nsview; + data.window = window; + data.nswindow = nswindow; + data.created = created; + data.videodata = videodata; + data.nscontexts = [[NSMutableArray alloc] init]; + data.sdlContentView = nsview; /* Create an event listener for the window */ - data->listener = [[Cocoa_WindowListener alloc] init]; + data.listener = [[Cocoa_WindowListener alloc] init]; /* Fill in the SDL window with the window data */ { @@ -1605,7 +1609,7 @@ SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, NSView *nsview, } /* Set up the listener after we create the view */ - [data->listener listen:data]; + [data.listener listen:data]; if ([nswindow isVisible]) { window->flags |= SDL_WINDOW_SHOWN; @@ -1646,16 +1650,22 @@ SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, NSView *nsview, if ([nswindow isKeyWindow]) { window->flags |= SDL_WINDOW_INPUT_FOCUS; - SDL_SetKeyboardFocus(data->window); + SDL_SetKeyboardFocus(data.window); } + /* SDL_WindowData will be holding a strong reference to the NSWindow, and + * it will also call [NSWindow close] in DestroyWindow before releasing the + * NSWindow, so the extra release provided by releasedWhenClosed isn't + * necessary. */ + nswindow.releasedWhenClosed = NO; + /* Prevents the window's "window device" from being destroyed when it is * hidden. See http://www.mikeash.com/pyblog/nsopenglcontext-and-one-shot.html */ [nswindow setOneShot:NO]; /* All done! */ - window->driverdata = data; + window->driverdata = (void *)CFBridgingRetain(data); return 0; }} @@ -1663,7 +1673,7 @@ int Cocoa_CreateWindow(_THIS, SDL_Window * window) { @autoreleasepool { - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *videodata = (__bridge SDL_VideoData *) _this->driverdata; NSWindow *nswindow; SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); NSRect rect; @@ -1708,9 +1718,7 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window) } #endif - if (videodata->allow_spaces) { - SDL_assert(floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6); - SDL_assert([nswindow respondsToSelector:@selector(toggleFullScreen:)]); + if (videodata.allow_spaces) { /* we put FULLSCREEN_DESKTOP windows in their own Space, without a toggle button or menubar, later */ if (window->flags & SDL_WINDOW_RESIZABLE) { /* resizable windows are Spaces-friendly: they get the "go fullscreen" toggle button on their titlebar. */ @@ -1734,10 +1742,8 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window) #endif /* Note: as of the macOS 10.15 SDK, this defaults to YES instead of NO when * the NSHighResolutionCapable boolean is set in Info.plist. */ - if ([contentView respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) { - BOOL highdpi = (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) != 0; - [contentView setWantsBestResolutionOpenGLSurface:highdpi]; - } + BOOL highdpi = (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) != 0; + [contentView setWantsBestResolutionOpenGLSurface:highdpi]; #ifdef __clang__ #pragma clang diagnostic pop #endif @@ -1751,10 +1757,8 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window) #endif /* SDL_VIDEO_OPENGL_EGL */ #endif /* SDL_VIDEO_OPENGL_ES2 */ [nswindow setContentView:contentView]; - [contentView release]; if (SetupWindowData(_this, window, nswindow, contentView, SDL_TRUE) < 0) { - [nswindow release]; return -1; } @@ -1786,11 +1790,11 @@ Cocoa_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) NSView* nsview = nil; NSWindow *nswindow = nil; - if ([(id)data isKindOfClass:[NSWindow class]]) { - nswindow = (NSWindow*)data; + if ([(__bridge id)data isKindOfClass:[NSWindow class]]) { + nswindow = (__bridge NSWindow*)data; nsview = [nswindow contentView]; - } else if ([(id)data isKindOfClass:[NSView class]]) { - nsview = (NSView*)data; + } else if ([(__bridge id)data isKindOfClass:[NSView class]]) { + nsview = (__bridge NSView*)data; nswindow = [nsview window]; } else { SDL_assert(false); @@ -1811,10 +1815,8 @@ Cocoa_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) #endif /* Note: as of the macOS 10.15 SDK, this defaults to YES instead of NO when * the NSHighResolutionCapable boolean is set in Info.plist. */ - if ([nsview respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) { - BOOL highdpi = (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) != 0; - [nsview setWantsBestResolutionOpenGLSurface:highdpi]; - } + BOOL highdpi = (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) != 0; + [nsview setWantsBestResolutionOpenGLSurface:highdpi]; #ifdef __clang__ #pragma clang diagnostic pop #endif @@ -1827,10 +1829,9 @@ Cocoa_SetWindowTitle(_THIS, SDL_Window * window) { @autoreleasepool { const char *title = window->title ? window->title : ""; - NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow; + NSWindow *nswindow = ((__bridge SDL_WindowData *) window->driverdata).nswindow; NSString *string = [[NSString alloc] initWithUTF8String:title]; [nswindow setTitle:string]; - [string release]; }} void @@ -1848,8 +1849,8 @@ void Cocoa_SetWindowPosition(_THIS, SDL_Window * window) { @autoreleasepool { - SDL_WindowData *windata = (SDL_WindowData *) window->driverdata; - NSWindow *nswindow = windata->nswindow; + SDL_WindowData *windata = (__bridge SDL_WindowData *) window->driverdata; + NSWindow *nswindow = windata.nswindow; NSRect rect; Uint32 moveHack; @@ -1871,8 +1872,8 @@ void Cocoa_SetWindowSize(_THIS, SDL_Window * window) { @autoreleasepool { - SDL_WindowData *windata = (SDL_WindowData *) window->driverdata; - NSWindow *nswindow = windata->nswindow; + SDL_WindowData *windata = (__bridge SDL_WindowData *) window->driverdata; + NSWindow *nswindow = windata.nswindow; NSRect rect; Uint32 moveHack; @@ -1898,39 +1899,39 @@ void Cocoa_SetWindowMinimumSize(_THIS, SDL_Window * window) { @autoreleasepool { - SDL_WindowData *windata = (SDL_WindowData *) window->driverdata; + SDL_WindowData *windata = (__bridge SDL_WindowData *) window->driverdata; NSSize minSize; minSize.width = window->min_w; minSize.height = window->min_h; - [windata->nswindow setContentMinSize:minSize]; + [windata.nswindow setContentMinSize:minSize]; }} void Cocoa_SetWindowMaximumSize(_THIS, SDL_Window * window) { @autoreleasepool { - SDL_WindowData *windata = (SDL_WindowData *) window->driverdata; + SDL_WindowData *windata = (__bridge SDL_WindowData *) window->driverdata; NSSize maxSize; maxSize.width = window->max_w; maxSize.height = window->max_h; - [windata->nswindow setContentMaxSize:maxSize]; + [windata.nswindow setContentMaxSize:maxSize]; }} void Cocoa_ShowWindow(_THIS, SDL_Window * window) { @autoreleasepool { - SDL_WindowData *windowData = ((SDL_WindowData *) window->driverdata); - NSWindow *nswindow = windowData->nswindow; + SDL_WindowData *windowData = ((__bridge SDL_WindowData *) window->driverdata); + NSWindow *nswindow = windowData.nswindow; if (![nswindow isMiniaturized]) { - [windowData->listener pauseVisibleObservation]; + [windowData.listener pauseVisibleObservation]; [nswindow makeKeyAndOrderFront:nil]; - [windowData->listener resumeVisibleObservation]; + [windowData.listener resumeVisibleObservation]; } }} @@ -1938,7 +1939,7 @@ void Cocoa_HideWindow(_THIS, SDL_Window * window) { @autoreleasepool { - NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow; + NSWindow *nswindow = ((__bridge SDL_WindowData *) window->driverdata).nswindow; [nswindow orderOut:nil]; }} @@ -1947,26 +1948,26 @@ void Cocoa_RaiseWindow(_THIS, SDL_Window * window) { @autoreleasepool { - SDL_WindowData *windowData = ((SDL_WindowData *) window->driverdata); - NSWindow *nswindow = windowData->nswindow; + SDL_WindowData *windowData = ((__bridge SDL_WindowData *) window->driverdata); + NSWindow *nswindow = windowData.nswindow; /* makeKeyAndOrderFront: has the side-effect of deminiaturizing and showing a minimized or hidden window, so check for that before showing it. */ - [windowData->listener pauseVisibleObservation]; + [windowData.listener pauseVisibleObservation]; if (![nswindow isMiniaturized] && [nswindow isVisible]) { [NSApp activateIgnoringOtherApps:YES]; [nswindow makeKeyAndOrderFront:nil]; } - [windowData->listener resumeVisibleObservation]; + [windowData.listener resumeVisibleObservation]; }} void Cocoa_MaximizeWindow(_THIS, SDL_Window * window) { @autoreleasepool { - SDL_WindowData *windata = (SDL_WindowData *) window->driverdata; - NSWindow *nswindow = windata->nswindow; + SDL_WindowData *windata = (__bridge SDL_WindowData *) window->driverdata; + NSWindow *nswindow = windata.nswindow; [nswindow zoom:nil]; @@ -1977,10 +1978,10 @@ void Cocoa_MinimizeWindow(_THIS, SDL_Window * window) { @autoreleasepool { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - NSWindow *nswindow = data->nswindow; - if ([data->listener isInFullscreenSpaceTransition]) { - [data->listener addPendingWindowOperation:PENDING_OPERATION_MINIMIZE]; + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; + NSWindow *nswindow = data.nswindow; + if ([data.listener isInFullscreenSpaceTransition]) { + [data.listener addPendingWindowOperation:PENDING_OPERATION_MINIMIZE]; } else { [nswindow miniaturize:nil]; } @@ -1990,7 +1991,7 @@ void Cocoa_RestoreWindow(_THIS, SDL_Window * window) { @autoreleasepool { - NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow; + NSWindow *nswindow = ((__bridge SDL_WindowData *) window->driverdata).nswindow; if ([nswindow isMiniaturized]) { [nswindow deminiaturize:nil]; @@ -2018,14 +2019,14 @@ Cocoa_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) * The window will get permanently stuck if resizable is false. * -flibit */ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - Cocoa_WindowListener *listener = data->listener; - NSWindow *nswindow = data->nswindow; - SDL_VideoData *videodata = ((SDL_WindowData *) window->driverdata)->videodata; + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; + Cocoa_WindowListener *listener = data.listener; + NSWindow *nswindow = data.nswindow; + SDL_VideoData *videodata = data.videodata; if (![listener isInFullscreenSpace]) { SetWindowStyle(window, GetWindowStyle(window)); } - if (videodata->allow_spaces) { + if (videodata.allow_spaces) { if (resizable) { /* resizable windows are Spaces-friendly: they get the "go fullscreen" toggle button on their titlebar. */ [nswindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; @@ -2039,7 +2040,7 @@ void Cocoa_SetWindowAlwaysOnTop(_THIS, SDL_Window * window, SDL_bool on_top) { @autoreleasepool { - NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow; + NSWindow *nswindow = ((__bridge SDL_WindowData *) window->driverdata).nswindow; if (on_top) { [nswindow setLevel:NSFloatingWindowLevel]; } else { @@ -2051,13 +2052,13 @@ void Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen) { @autoreleasepool { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - NSWindow *nswindow = data->nswindow; + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; + NSWindow *nswindow = data.nswindow; NSRect rect; /* The view responder chain gets messed with during setStyleMask */ - if ([data->sdlContentView nextResponder] == data->listener) { - [data->sdlContentView setNextResponder:nil]; + if ([data.sdlContentView nextResponder] == data.listener) { + [data.sdlContentView setNextResponder:nil]; } if (fullscreen) { @@ -2103,8 +2104,8 @@ Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display } /* The view responder chain gets messed with during setStyleMask */ - if ([data->sdlContentView nextResponder] != data->listener) { - [data->sdlContentView setNextResponder:data->listener]; + if ([data.sdlContentView nextResponder] != data.listener) { + [data.sdlContentView setNextResponder:data.listener]; } s_moveHack = 0; @@ -2127,9 +2128,9 @@ Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display } if ([nswindow isVisible] || fullscreen) { - [data->listener pauseVisibleObservation]; + [data.listener pauseVisibleObservation]; [nswindow makeKeyAndOrderFront:nil]; - [data->listener resumeVisibleObservation]; + [data.listener resumeVisibleObservation]; } ScheduleContextUpdates(data); @@ -2137,6 +2138,7 @@ Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display int Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) +{ @autoreleasepool { SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); CGDirectDisplayID display_id = ((SDL_DisplayData *)display->driverdata)->display; @@ -2159,13 +2161,14 @@ Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) return SDL_SetError("CGSetDisplayTransferByTable()"); } return 0; -} +}} void* Cocoa_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size) +{ @autoreleasepool { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - NSWindow *nswindow = data->nswindow; + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; + NSWindow *nswindow = data.nswindow; NSScreen *screen = [nswindow screen]; NSData* iccProfileData = nil; void* retIccProfileData = NULL; @@ -2195,7 +2198,40 @@ Cocoa_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size) [iccProfileData getBytes:retIccProfileData length:[iccProfileData length]]; *size = [iccProfileData length]; return retIccProfileData; -} +}} + +int +Cocoa_GetWindowDisplayIndex(_THIS, SDL_Window * window) +{ @autoreleasepool +{ + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; + + /* Not recognized via CHECK_WINDOW_MAGIC */ + if (data == NULL){ + return 0; + } + + /* + Considering that we already have the display coordinates in which the window is placed (described via displayframe) + instead of checking in which display the window is placed, we should check which SDL display matches the display described + via displayframe. + */ + NSRect displayframe = data.nswindow.screen.frame; + SDL_Point display_center; + SDL_Rect sdl_display_rect; + + display_center.x = displayframe.origin.x + displayframe.size.width / 2; + display_center.y = displayframe.origin.y + displayframe.size.height / 2; + + for (int i = 0; i < SDL_GetNumVideoDisplays(); i++){ + SDL_GetDisplayBounds(i, &sdl_display_rect); + if (SDL_EnclosePoints(&display_center, 1, &sdl_display_rect, NULL)) { + return i; + } + } + SDL_SetError("Couldn't find the display where the window is attached to."); + return -1; +}} int Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp) @@ -2229,59 +2265,58 @@ Cocoa_SetWindowMouseRect(_THIS, SDL_Window * window) void Cocoa_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +{ @autoreleasepool { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; Cocoa_UpdateClipCursor(window); if (data && (window->flags & SDL_WINDOW_FULLSCREEN)) { if (SDL_ShouldAllowTopmost() && (window->flags & SDL_WINDOW_INPUT_FOCUS) - && ![data->listener isInFullscreenSpace]) { + && ![data.listener isInFullscreenSpace]) { /* OpenGL is rendering to the window, so make it visible! */ /* Doing this in 10.11 while in a Space breaks things (bug #3152) */ - [data->nswindow setLevel:CGShieldingWindowLevel()]; + [data.nswindow setLevel:CGShieldingWindowLevel()]; } else if (window->flags & SDL_WINDOW_ALWAYS_ON_TOP) { - [data->nswindow setLevel:NSFloatingWindowLevel]; + [data.nswindow setLevel:NSFloatingWindowLevel]; } else { - [data->nswindow setLevel:kCGNormalWindowLevel]; + [data.nswindow setLevel:kCGNormalWindowLevel]; } } -} +}} void Cocoa_DestroyWindow(_THIS, SDL_Window * window) { @autoreleasepool { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *) CFBridgingRelease(window->driverdata); if (data) { - if ([data->listener isInFullscreenSpace]) { + if ([data.listener isInFullscreenSpace]) { [NSMenu setMenuBarVisible:YES]; } - [data->listener close]; - [data->listener release]; - if (data->created) { + [data.listener close]; + data.listener = nil; + if (data.created) { /* Release the content view to avoid further updateLayer callbacks */ - [data->nswindow setContentView:nil]; - [data->nswindow close]; + [data.nswindow setContentView:nil]; + [data.nswindow close]; } - NSArray *contexts = [[data->nscontexts copy] autorelease]; + NSArray *contexts = [data.nscontexts copy]; for (SDLOpenGLContext *context in contexts) { /* Calling setWindow:NULL causes the context to remove itself from the context list. */ [context setWindow:NULL]; } - [data->nscontexts release]; - - SDL_free(data); } window->driverdata = NULL; }} SDL_bool Cocoa_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) +{ @autoreleasepool { - NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow; + NSWindow *nswindow = ((__bridge SDL_WindowData *) window->driverdata).nswindow; if (info->version.major <= SDL_MAJOR_VERSION) { info->subsystem = SDL_SYSWM_COCOA; @@ -2292,33 +2327,34 @@ Cocoa_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) SDL_MAJOR_VERSION, SDL_MINOR_VERSION); return SDL_FALSE; } -} +}} SDL_bool Cocoa_IsWindowInFullscreenSpace(SDL_Window * window) +{ @autoreleasepool { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; - if ([data->listener isInFullscreenSpace]) { + if ([data.listener isInFullscreenSpace]) { return SDL_TRUE; } else { return SDL_FALSE; } -} +}} SDL_bool Cocoa_SetWindowFullscreenSpace(SDL_Window * window, SDL_bool state) { @autoreleasepool { SDL_bool succeeded = SDL_FALSE; - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; - if (data->inWindowFullscreenTransition) { + if (data.inWindowFullscreenTransition) { return SDL_FALSE; } - data->inWindowFullscreenTransition = SDL_TRUE; - if ([data->listener setFullscreenSpace:(state ? YES : NO)]) { + data.inWindowFullscreenTransition = SDL_TRUE; + if ([data.listener setFullscreenSpace:(state ? YES : NO)]) { const int maxattempts = 3; int attempt = 0; while (++attempt <= maxattempts) { @@ -2327,7 +2363,7 @@ Cocoa_SetWindowFullscreenSpace(SDL_Window * window, SDL_bool state) */ const int limit = 10000; int count = 0; - while ([data->listener isInFullscreenSpaceTransition]) { + while ([data.listener isInFullscreenSpaceTransition]) { if ( ++count == limit ) { /* Uh oh, transition isn't completing. Should we assert? */ break; @@ -2335,16 +2371,16 @@ Cocoa_SetWindowFullscreenSpace(SDL_Window * window, SDL_bool state) SDL_Delay(1); SDL_PumpEvents(); } - if ([data->listener isInFullscreenSpace] == (state ? YES : NO)) + if ([data.listener isInFullscreenSpace] == (state ? YES : NO)) break; /* Try again, the last attempt was interrupted by user gestures */ - if (![data->listener setFullscreenSpace:(state ? YES : NO)]) + if (![data.listener setFullscreenSpace:(state ? YES : NO)]) break; /* ??? */ } /* Return TRUE to prevent non-space fullscreen logic from running */ succeeded = SDL_TRUE; } - data->inWindowFullscreenTransition = SDL_FALSE; + data.inWindowFullscreenTransition = SDL_FALSE; return succeeded; }} @@ -2357,25 +2393,26 @@ Cocoa_SetWindowHitTest(SDL_Window * window, SDL_bool enabled) void Cocoa_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept) +{ @autoreleasepool { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; if (accept) { - [data->nswindow registerForDraggedTypes:[NSArray arrayWithObject:(NSString *)kUTTypeFileURL]]; + [data.nswindow registerForDraggedTypes:[NSArray arrayWithObject:(NSString *)kUTTypeFileURL]]; } else { - [data->nswindow unregisterDraggedTypes]; + [data.nswindow unregisterDraggedTypes]; } -} +}} int Cocoa_FlashWindow(_THIS, SDL_Window *window, SDL_FlashOperation operation) { @autoreleasepool { /* Note that this is app-wide and not window-specific! */ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; - if (data->flash_request) { - [NSApp cancelUserAttentionRequest:data->flash_request]; - data->flash_request = 0; + if (data.flash_request) { + [NSApp cancelUserAttentionRequest:data.flash_request]; + data.flash_request = 0; } switch (operation) { @@ -2383,10 +2420,10 @@ Cocoa_FlashWindow(_THIS, SDL_Window *window, SDL_FlashOperation operation) /* Canceled above */ break; case SDL_FLASH_BRIEFLY: - data->flash_request = [NSApp requestUserAttention:NSInformationalRequest]; + data.flash_request = [NSApp requestUserAttention:NSInformationalRequest]; break; case SDL_FLASH_UNTIL_FOCUSED: - data->flash_request = [NSApp requestUserAttention:NSCriticalRequest]; + data.flash_request = [NSApp requestUserAttention:NSCriticalRequest]; break; default: return SDL_Unsupported(); @@ -2396,11 +2433,12 @@ Cocoa_FlashWindow(_THIS, SDL_Window *window, SDL_FlashOperation operation) int Cocoa_SetWindowOpacity(_THIS, SDL_Window * window, float opacity) +{ @autoreleasepool { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - [data->nswindow setAlphaValue:opacity]; + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; + [data.nswindow setAlphaValue:opacity]; return 0; -} +}} #endif /* SDL_VIDEO_DRIVER_COCOA */ diff --git a/src/video/kmsdrm/SDL_kmsdrmsym.h b/src/video/kmsdrm/SDL_kmsdrmsym.h index 52c78de5e..f53c5c8ea 100644 --- a/src/video/kmsdrm/SDL_kmsdrmsym.h +++ b/src/video/kmsdrm/SDL_kmsdrmsym.h @@ -19,7 +19,7 @@ 3. This notice may not be removed or altered from any source distribution. */ -/* *INDENT-OFF* */ +/* *INDENT-OFF* */ /* clang-format off */ #ifndef SDL_KMSDRM_MODULE #define SDL_KMSDRM_MODULE(modname) @@ -125,6 +125,6 @@ SDL_KMSDRM_SYM(void,gbm_surface_release_buffer,(struct gbm_surface *surf, struct #undef SDL_KMSDRM_SYM #undef SDL_KMSDRM_SYM_CONST -/* *INDENT-ON* */ +/* *INDENT-ON* */ /* clang-format on */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/ngage/SDL_ngageevents.cpp b/src/video/ngage/SDL_ngageevents.cpp new file mode 100644 index 000000000..a13633376 --- /dev/null +++ b/src/video/ngage/SDL_ngageevents.cpp @@ -0,0 +1,200 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_NGAGE + +/* Being a ngage driver, there's no event stream. We just define stubs for + most of the API. */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../../events/SDL_events_c.h" +#include "../../events/SDL_keyboard_c.h" + +#ifdef __cplusplus +} +#endif + +#include "SDL_ngagevideo.h" +#include "SDL_ngageevents_c.h" + +int HandleWsEvent(_THIS, const TWsEvent& aWsEvent); + +void +NGAGE_PumpEvents(_THIS) +{ + SDL_VideoData *phdata = (SDL_VideoData*)_this->driverdata; + + while (phdata->NGAGE_WsEventStatus != KRequestPending) + { + phdata->NGAGE_WsSession.GetEvent(phdata->NGAGE_WsEvent); + + HandleWsEvent(_this, phdata->NGAGE_WsEvent); + + phdata->NGAGE_WsEventStatus = KRequestPending; + phdata->NGAGE_WsSession.EventReady(&phdata->NGAGE_WsEventStatus); + } +} + +/*****************************************************************************/ +/* Internal */ +/*****************************************************************************/ + +#include +#include + +extern void DisableKeyBlocking(_THIS); +extern void RedrawWindowL(_THIS); + +TBool isCursorVisible = EFalse; + +static SDL_Scancode ConvertScancode(_THIS, int key) +{ + SDL_Keycode keycode; + + switch(key) + { + case EStdKeyBackspace: // Clear key + keycode = SDLK_BACKSPACE; + break; + case 0x31: // 1 + keycode = SDLK_1; + break; + case 0x32: // 2 + keycode = SDLK_2; + break; + case 0x33: // 3 + keycode = SDLK_3; + break; + case 0x34: // 4 + keycode = SDLK_4; + break; + case 0x35: // 5 + keycode = SDLK_5; + break; + case 0x36: // 6 + keycode = SDLK_6; + break; + case 0x37: // 7 + keycode = SDLK_7; + break; + case 0x38: // 8 + keycode = SDLK_8; + break; + case 0x39: // 9 + keycode = SDLK_9; + break; + case 0x30: // 0 + keycode = SDLK_0; + break; + case 0x2a: // Asterisk + keycode = SDLK_ASTERISK; + break; + case EStdKeyHash: // Hash + keycode = SDLK_HASH; + break; + case EStdKeyDevice0: // Left softkey + keycode = SDLK_SOFTLEFT; + break; + case EStdKeyDevice1: // Right softkey + keycode = SDLK_SOFTRIGHT; + break; + case EStdKeyApplication0: // Call softkey + keycode = SDLK_CALL; + break; + case EStdKeyApplication1: // End call softkey + keycode = SDLK_ENDCALL; + break; + case EStdKeyDevice3: // Middle softkey + keycode = SDLK_SELECT; + break; + case EStdKeyUpArrow: // Up arrow + keycode = SDLK_UP; + break; + case EStdKeyDownArrow: // Down arrow + keycode = SDLK_DOWN; + break; + case EStdKeyLeftArrow: // Left arrow + keycode = SDLK_LEFT; + break; + case EStdKeyRightArrow: // Right arrow + keycode = SDLK_RIGHT; + break; + default: + keycode = SDLK_UNKNOWN; + break; + } + + return SDL_GetScancodeFromKey(keycode); +} + +int HandleWsEvent(_THIS, const TWsEvent& aWsEvent) +{ + SDL_VideoData *phdata = (SDL_VideoData*)_this->driverdata; + int posted = 0; + + switch (aWsEvent.Type()) + { + case EEventKeyDown: /* Key events */ + SDL_SendKeyboardKey(SDL_PRESSED, ConvertScancode(_this, aWsEvent.Key()->iScanCode)); + break; + case EEventKeyUp: /* Key events */ + SDL_SendKeyboardKey(SDL_RELEASED, ConvertScancode(_this, aWsEvent.Key()->iScanCode)); + break; + case EEventFocusGained: /* SDL window got focus */ + phdata->NGAGE_IsWindowFocused = ETrue; + /* Draw window background and screen buffer */ + DisableKeyBlocking(_this); + RedrawWindowL(_this); + break; + case EEventFocusLost: /* SDL window lost focus */ + { + phdata->NGAGE_IsWindowFocused = EFalse; + RWsSession s; + s.Connect(); + RWindowGroup g(s); + g.Construct(TUint32(&g), EFalse); + g.EnableReceiptOfFocus(EFalse); + RWindow w(s); + w.Construct(g, TUint32(&w)); + w.SetExtent(TPoint(0, 0), phdata->NGAGE_WsWindow.Size()); + w.SetOrdinalPosition(0); + w.Activate(); + w.Close(); + g.Close(); + s.Close(); + break; + } + case EEventModifiersChanged: + break; + default: + break; + } + return posted; +} + +#endif /* SDL_VIDEO_DRIVER_NGAGE */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/ngage/SDL_ngageevents_c.h b/src/video/ngage/SDL_ngageevents_c.h new file mode 100644 index 000000000..c7b58ce40 --- /dev/null +++ b/src/video/ngage/SDL_ngageevents_c.h @@ -0,0 +1,28 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + 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_ngagevideo.h" + +extern void NGAGE_PumpEvents(_THIS); + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/ngage/SDL_ngageframebuffer.cpp b/src/video/ngage/SDL_ngageframebuffer.cpp new file mode 100644 index 000000000..a67fa5a8a --- /dev/null +++ b/src/video/ngage/SDL_ngageframebuffer.cpp @@ -0,0 +1,431 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_NGAGE + +#include + +#include "../SDL_sysvideo.h" +#include "SDL_ngagevideo.h" +#include "SDL_ngageframebuffer_c.h" + +#define NGAGE_SURFACE "NGAGE_FrameBuffer" + +/* For 12 bit screen HW. Table for fast conversion from 8 bit to 12 bit + * + * TUint16 is enough, but using TUint32 so we can use better instruction + * selection on ARMI. + */ +static TUint32 NGAGE_HWPalette_256_to_Screen[256]; + +int GetBpp(TDisplayMode displaymode); +void DirectUpdate(_THIS, int numrects, SDL_Rect *rects); +void DrawBackground(_THIS); +void DirectDraw(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer); +void RedrawWindowL(_THIS); + +int SDL_NGAGE_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) +{ + SDL_VideoData *phdata = (SDL_VideoData*)_this->driverdata; + SDL_Surface *surface; + const Uint32 surface_format = SDL_PIXELFORMAT_RGB444; + int w, h; + + /* Free the old framebuffer surface */ + SDL_NGAGE_DestroyWindowFramebuffer(_this, window); + + /* Create a new one */ + SDL_GetWindowSize(window, &w, &h); + surface = SDL_CreateRGBSurfaceWithFormat(0, w, h, 0, surface_format); + if (! surface) { + return -1; + } + + /* Save the info and return! */ + SDL_SetWindowData(window, NGAGE_SURFACE, surface); + *format = surface_format; + *pixels = surface->pixels; + *pitch = surface->pitch; + + /* Initialise Epoc frame buffer */ + + TDisplayMode displayMode = phdata->NGAGE_WsScreen->DisplayMode(); + + TScreenInfoV01 screenInfo; + TPckg sInfo(screenInfo); + UserSvr::ScreenInfo(sInfo); + + phdata->NGAGE_ScreenSize = screenInfo.iScreenSize; + phdata->NGAGE_DisplayMode = displayMode; + phdata->NGAGE_HasFrameBuffer = screenInfo.iScreenAddressValid; + phdata->NGAGE_FrameBuffer = phdata->NGAGE_HasFrameBuffer ? (TUint8*) screenInfo.iScreenAddress : NULL; + phdata->NGAGE_BytesPerPixel = ((GetBpp(displayMode)-1) / 8) + 1; + + phdata->NGAGE_BytesPerScanLine = screenInfo.iScreenSize.iWidth * phdata->NGAGE_BytesPerPixel; + phdata->NGAGE_BytesPerScreen = phdata->NGAGE_BytesPerScanLine * phdata->NGAGE_ScreenSize.iHeight; + + SDL_Log("Screen width %d", screenInfo.iScreenSize.iWidth); + SDL_Log("Screen height %d", screenInfo.iScreenSize.iHeight); + SDL_Log("Screen dmode %d", displayMode); + SDL_Log("Screen valid %d", screenInfo.iScreenAddressValid); + + SDL_Log("Bytes per pixel %d", phdata->NGAGE_BytesPerPixel); + SDL_Log("Bytes per scan line %d", phdata->NGAGE_BytesPerScanLine); + SDL_Log("Bytes per screen %d", phdata->NGAGE_BytesPerScreen); + + /* It seems that in SA1100 machines for 8bpp displays there is a 512 + * palette table at the beginning of the frame buffer. + * + * In 12 bpp machines the table has 16 entries. + */ + if (phdata->NGAGE_HasFrameBuffer && GetBpp(displayMode) == 8) + { + phdata->NGAGE_FrameBuffer += 512; + } + else + { + phdata->NGAGE_FrameBuffer += 32; + } + #if 0 + if (phdata->NGAGE_HasFrameBuffer && GetBpp(displayMode) == 12) + { + phdata->NGAGE_FrameBuffer += 16 * 2; + } + if (phdata->NGAGE_HasFrameBuffer && GetBpp(displayMode) == 16) + { + phdata->NGAGE_FrameBuffer += 16 * 2; + } + #endif + + // Get draw device for updating the screen + TScreenInfoV01 screenInfo2; + + NGAGE_Runtime::GetScreenInfo(screenInfo2); + + TRAPD(status, phdata->NGAGE_DrawDevice = CFbsDrawDevice::NewScreenDeviceL(screenInfo2, displayMode)); + User::LeaveIfError(status); + + /* Activate events for me */ + phdata->NGAGE_WsEventStatus = KRequestPending; + phdata->NGAGE_WsSession.EventReady(&phdata->NGAGE_WsEventStatus); + + SDL_Log("SDL:WsEventStatus"); + User::WaitForRequest(phdata->NGAGE_WsEventStatus); + + phdata->NGAGE_RedrawEventStatus = KRequestPending; + phdata->NGAGE_WsSession.RedrawReady(&phdata->NGAGE_RedrawEventStatus); + + SDL_Log("SDL:RedrawEventStatus"); + User::WaitForRequest(phdata->NGAGE_RedrawEventStatus); + + phdata->NGAGE_WsWindow.PointerFilter(EPointerFilterDrag, 0); + + phdata->NGAGE_ScreenOffset = TPoint(0, 0); + + SDL_Log("SDL:DrawBackground"); + DrawBackground(_this); // Clear screen + + return 0; +} + +int SDL_NGAGE_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects) +{ + static int frame_number; + SDL_Surface *surface; + + surface = (SDL_Surface *) SDL_GetWindowData(window, NGAGE_SURFACE); + if (! surface) + { + return SDL_SetError("Couldn't find ngage surface for window"); + } + + /* Send the data to the display */ + if (SDL_getenv("SDL_VIDEO_NGAGE_SAVE_FRAMES")) + { + char file[128]; + SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp", + (int)SDL_GetWindowID(window), ++frame_number); + SDL_SaveBMP(surface, file); + } + + DirectUpdate(_this, numrects, (SDL_Rect*)rects); + + return 0; +} + +void SDL_NGAGE_DestroyWindowFramebuffer(_THIS, SDL_Window * window) +{ + SDL_Surface *surface; + + surface = (SDL_Surface *) SDL_SetWindowData(window, NGAGE_SURFACE, NULL); + SDL_FreeSurface(surface); +} + +/*****************************************************************************/ +/* Runtime */ +/*****************************************************************************/ + +#include +#include +#include + +EXPORT_C void NGAGE_Runtime::GetScreenInfo(TScreenInfoV01& screenInfo2) +{ + TPckg sInfo2(screenInfo2); + UserSvr::ScreenInfo(sInfo2); +} + +/*****************************************************************************/ +/* Internal */ +/*****************************************************************************/ + +int GetBpp(TDisplayMode displaymode) +{ + return TDisplayModeUtils::NumDisplayModeBitsPerPixel(displaymode); +} + +void DrawBackground(_THIS) +{ + SDL_VideoData *phdata = (SDL_VideoData*)_this->driverdata; + /* Draw background */ + TUint16* screenBuffer = (TUint16*)phdata->NGAGE_FrameBuffer; + /* Draw black background */ + Mem::FillZ(screenBuffer, phdata->NGAGE_BytesPerScreen); +} + +void DirectDraw(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer) +{ + SDL_VideoData *phdata = (SDL_VideoData*)_this->driverdata; + SDL_Surface *screen = (SDL_Surface*)SDL_GetWindowData(_this->windows, NGAGE_SURFACE); + + TInt i; + + //const TInt sourceNumBytesPerPixel = ((screen->format->BitsPerPixel-1) >> 3) + 1; + TDisplayMode displayMode = phdata->NGAGE_DisplayMode; + const TInt sourceNumBytesPerPixel = ((GetBpp(displayMode)-1) / 8) + 1; + // + const TPoint fixedOffset = phdata->NGAGE_ScreenOffset; + const TInt screenW = screen->w; + const TInt screenH = screen->h; + const TInt sourceScanlineLength = screenW; + const TInt targetScanlineLength = phdata->NGAGE_ScreenSize.iWidth; + + /* Render the rectangles in the list */ + + for (i = 0; i < numrects; ++i) + { + const SDL_Rect& currentRect = rects[i]; + SDL_Rect rect2; + rect2.x = currentRect.x; + rect2.y = currentRect.y; + rect2.w = currentRect.w; + rect2.h = currentRect.h; + + if (rect2.w <= 0 || rect2.h <= 0) /* Sanity check */ + { + continue; + } + + /* All variables are measured in pixels */ + + /* Check rects validity, i.e. upper and lower bounds */ + TInt maxX = Min(screenW - 1, rect2.x + rect2.w - 1); + TInt maxY = Min(screenH - 1, rect2.y + rect2.h - 1); + if (maxX < 0 || maxY < 0) /* sanity check */ + { + continue; + } + /* Clip from bottom */ + + maxY = Min(maxY, phdata->NGAGE_ScreenSize.iHeight-1); + /* TODO: Clip from the right side */ + + const TInt sourceRectWidth = maxX - rect2.x + 1; + const TInt sourceRectWidthInBytes = sourceRectWidth * sourceNumBytesPerPixel; + const TInt sourceRectHeight = maxY - rect2.y + 1; + const TInt sourceStartOffset = rect2.x + rect2.y * sourceScanlineLength; + const TUint skipValue = 1; /* 1 = No skip */ + + TInt targetStartOffset = fixedOffset.iX + rect2.x + (fixedOffset.iY +rect2.y) * targetScanlineLength; + + switch (screen->format->BitsPerPixel) + { + case 12: + { + TUint16* bitmapLine = (TUint16*)screen->pixels + sourceStartOffset; + TUint16* screenMemory = screenBuffer + targetStartOffset; + + if (skipValue == 1) + { + for(TInt y = 0 ; y < sourceRectHeight ; y++) + { + Mem::Copy(screenMemory, bitmapLine, sourceRectWidthInBytes); + bitmapLine += sourceScanlineLength; + screenMemory += targetScanlineLength; + } + } + else + { + for(TInt y = 0 ; y < sourceRectHeight ; y++) + { + TUint16* bitmapPos = bitmapLine; /* 2 bytes per pixel */ + TUint16* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */ + for(TInt x = 0 ; x < sourceRectWidth ; x++) + { + __ASSERT_DEBUG(screenMemory < (screenBuffer + phdata->NGAGE_ScreenSize.iWidth * phdata->NGAGE_ScreenSize.iHeight), User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(screenMemory >= screenBuffer, User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(bitmapLine < ((TUint16*)screen->pixels + (screen->w * screen->h)), User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(bitmapLine >= (TUint16*)screen->pixels, User::Panic(_L("SDL"), KErrCorrupt)); + + *screenMemoryLinePos++ = *bitmapPos; + bitmapPos += skipValue; + } + bitmapLine += sourceScanlineLength; + screenMemory += targetScanlineLength; + } + } + } + break; + // 256 color paletted mode: 8 bpp --> 12 bpp + default: + { + if(phdata->NGAGE_BytesPerPixel <= 2) + { + TUint8* bitmapLine = (TUint8*)screen->pixels + sourceStartOffset; + TUint16* screenMemory = screenBuffer + targetStartOffset; + + for(TInt y = 0 ; y < sourceRectHeight ; y++) + { + TUint8* bitmapPos = bitmapLine; /* 1 byte per pixel */ + TUint16* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */ + /* Convert each pixel from 256 palette to 4k color values */ + for(TInt x = 0 ; x < sourceRectWidth ; x++) + { + __ASSERT_DEBUG(screenMemoryLinePos < (screenBuffer + (phdata->NGAGE_ScreenSize.iWidth * phdata->NGAGE_ScreenSize.iHeight)), User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(screenMemoryLinePos >= screenBuffer, User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(bitmapPos < ((TUint8*)screen->pixels + (screen->w * screen->h)), User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(bitmapPos >= (TUint8*)screen->pixels, User::Panic(_L("SDL"), KErrCorrupt)); + *screenMemoryLinePos++ = NGAGE_HWPalette_256_to_Screen[*bitmapPos++]; + } + bitmapLine += sourceScanlineLength; + screenMemory += targetScanlineLength; + } + } + else + { + TUint8* bitmapLine = (TUint8*)screen->pixels + sourceStartOffset; + TUint32* screenMemory = reinterpret_cast(screenBuffer + targetStartOffset); + for(TInt y = 0 ; y < sourceRectHeight ; y++) + { + TUint8* bitmapPos = bitmapLine; /* 1 byte per pixel */ + TUint32* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */ + /* Convert each pixel from 256 palette to 4k color values */ + for(TInt x = 0 ; x < sourceRectWidth ; x++) + { + __ASSERT_DEBUG(screenMemoryLinePos < (reinterpret_cast(screenBuffer) + (phdata->NGAGE_ScreenSize.iWidth * phdata->NGAGE_ScreenSize.iHeight)), User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(screenMemoryLinePos >= reinterpret_cast(screenBuffer), User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(bitmapPos < ((TUint8*)screen->pixels + (screen->w * screen->h)), User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(bitmapPos >= (TUint8*)screen->pixels, User::Panic(_L("SDL"), KErrCorrupt)); + *screenMemoryLinePos++ = NGAGE_HWPalette_256_to_Screen[*bitmapPos++]; + } + bitmapLine += sourceScanlineLength; + screenMemory += targetScanlineLength; + } + } + } + } + } +} + +void DirectUpdate(_THIS, int numrects, SDL_Rect *rects) +{ + SDL_VideoData *phdata = (SDL_VideoData*)_this->driverdata; + + if (! phdata->NGAGE_IsWindowFocused) + { + SDL_PauseAudio(1); + SDL_Delay(1000); + return; + } + + SDL_PauseAudio(0); + + TUint16* screenBuffer = (TUint16*)phdata->NGAGE_FrameBuffer; + +#if 0 + if (phdata->NGAGE_ScreenOrientation == CFbsBitGc::EGraphicsOrientationRotated270) + { + // ... + } + else +#endif + { + DirectDraw(_this, numrects, rects, screenBuffer); + } + + //TRect rect2 = TRect(phdata->NGAGE_WsWindow.Size()); + for (int i = 0; i < numrects; ++i) + { + TInt aAx = rects[i].x; + TInt aAy = rects[i].y; + TInt aBx = rects[i].w; + TInt aBy = rects[i].h; + TRect rect2 = TRect(aAx, aAy, aBx, aBy); + + phdata->NGAGE_DrawDevice->UpdateRegion(rect2); /* Should we update rects parameter area only? */ + phdata->NGAGE_DrawDevice->Update(); + } +} + +void RedrawWindowL(_THIS) +{ + SDL_VideoData *phdata = (SDL_VideoData*)_this->driverdata; + SDL_Surface *screen = (SDL_Surface*)SDL_GetWindowData(_this->windows, NGAGE_SURFACE); + + int w = screen->w; + int h = screen->h; + if (phdata->NGAGE_ScreenOrientation == CFbsBitGc::EGraphicsOrientationRotated270) { + w = screen->h; + h = screen->w; + } + if ((w < phdata->NGAGE_ScreenSize.iWidth) + || (h < phdata->NGAGE_ScreenSize.iHeight)) { + DrawBackground(_this); + } + + /* Tell the system that something has been drawn */ + TRect rect = TRect(phdata->NGAGE_WsWindow.Size()); + phdata->NGAGE_WsWindow.Invalidate(rect); + + /* Draw current buffer */ + SDL_Rect fullScreen; + fullScreen.x = 0; + fullScreen.y = 0; + fullScreen.w = screen->w; + fullScreen.h = screen->h; + DirectUpdate(_this, 1, &fullScreen); +} + +#endif /* SDL_VIDEO_DRIVER_NGAGE */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/ngage/SDL_ngageframebuffer_c.h b/src/video/ngage/SDL_ngageframebuffer_c.h new file mode 100644 index 000000000..c2f0768ca --- /dev/null +++ b/src/video/ngage/SDL_ngageframebuffer_c.h @@ -0,0 +1,38 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + 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" + +extern int SDL_NGAGE_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch); +extern int SDL_NGAGE_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects); +extern void SDL_NGAGE_DestroyWindowFramebuffer(_THIS, SDL_Window * window); + +/****************************************************************************/ +/* Runtime */ +/****************************************************************************/ + +class NGAGE_Runtime +{ +public: + IMPORT_C static void GetScreenInfo(TScreenInfoV01& screenInfo2); +}; + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/ngage/SDL_ngagevideo.cpp b/src/video/ngage/SDL_ngagevideo.cpp new file mode 100644 index 000000000..eea21e8e1 --- /dev/null +++ b/src/video/ngage/SDL_ngagevideo.cpp @@ -0,0 +1,192 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + 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 +#ifdef NULL +#undef NULL +#endif +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_NGAGE + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SDL_video.h" +#include "../SDL_sysvideo.h" +#include "../SDL_pixels_c.h" +#include "../../events/SDL_events_c.h" + +#ifdef __cplusplus +} +#endif + +#include "SDL_ngagevideo.h" +#include "SDL_ngagewindow.h" +#include "SDL_ngageevents_c.h" +#include "SDL_ngageframebuffer_c.h" + +#define NGAGEVID_DRIVER_NAME "ngage" + +/* Initialization/Query functions */ +static int NGAGE_VideoInit(_THIS); +static int NGAGE_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); +static void NGAGE_VideoQuit(_THIS); + +/* NGAGE driver bootstrap functions */ + +static void +NGAGE_DeleteDevice(SDL_VideoDevice * device) +{ + SDL_VideoData *phdata = (SDL_VideoData*)device->driverdata; + + if (phdata) + { + /* Free Epoc resources */ + + /* Disable events for me */ + if (phdata->NGAGE_WsEventStatus != KRequestPending) + { + phdata->NGAGE_WsSession.EventReadyCancel(); + } + if (phdata->NGAGE_RedrawEventStatus != KRequestPending) + { + phdata->NGAGE_WsSession.RedrawReadyCancel(); + } + + free(phdata->NGAGE_DrawDevice); + + if (phdata->NGAGE_WsWindow.WsHandle()) + { + phdata->NGAGE_WsWindow.Close(); + } + + if (phdata->NGAGE_WsWindowGroup.WsHandle()) + { + phdata->NGAGE_WsWindowGroup.Close(); + } + + delete phdata->NGAGE_WindowGc; + phdata->NGAGE_WindowGc = NULL; + + delete phdata->NGAGE_WsScreen; + phdata->NGAGE_WsScreen = NULL; + + if (phdata->NGAGE_WsSession.WsHandle()) + { + phdata->NGAGE_WsSession.Close(); + } + + SDL_free(phdata); + phdata = NULL; + } + + if (device) + { + SDL_free(device); + device = NULL; + } +} + +static SDL_VideoDevice * +NGAGE_CreateDevice(int devindex) +{ + SDL_VideoDevice *device; + SDL_VideoData *phdata; + + /* Initialize all variables that we clean on shutdown */ + device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (!device) { + SDL_OutOfMemory(); + return (0); + } + + /* Initialize internal N-Gage specific data */ + phdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); + if (! phdata) + { + SDL_OutOfMemory(); + SDL_free(device); + return (0); + } + + /* General video */ + device->VideoInit = NGAGE_VideoInit; + device->VideoQuit = NGAGE_VideoQuit; + device->SetDisplayMode = NGAGE_SetDisplayMode; + device->PumpEvents = NGAGE_PumpEvents; + device->CreateWindowFramebuffer = SDL_NGAGE_CreateWindowFramebuffer; + device->UpdateWindowFramebuffer = SDL_NGAGE_UpdateWindowFramebuffer; + device->DestroyWindowFramebuffer = SDL_NGAGE_DestroyWindowFramebuffer; + device->free = NGAGE_DeleteDevice; + + /* "Window" */ + device->CreateSDLWindow = NGAGE_CreateWindow; + device->DestroyWindow = NGAGE_DestroyWindow; + + /* N-Gage specific data */ + device->driverdata = phdata; + + return device; +} + +VideoBootStrap NGAGE_bootstrap = { + NGAGEVID_DRIVER_NAME, "SDL ngage video driver", + NGAGE_CreateDevice +}; + +int +NGAGE_VideoInit(_THIS) +{ + SDL_DisplayMode mode; + + /* Use 12-bpp desktop mode */ + mode.format = SDL_PIXELFORMAT_RGB444; + mode.w = 176; + mode.h = 208; + mode.refresh_rate = 0; + mode.driverdata = NULL; + if (SDL_AddBasicVideoDisplay(&mode) < 0) { + return -1; + } + + SDL_zero(mode); + SDL_AddDisplayMode(&_this->displays[0], &mode); + + /* We're done! */ + return 0; +} + +static int +NGAGE_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +{ + return 0; +} + +void +NGAGE_VideoQuit(_THIS) +{ +} + +#endif /* SDL_VIDEO_DRIVER_NGAGE */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/ngage/SDL_ngagevideo.h b/src/video/ngage/SDL_ngagevideo.h new file mode 100644 index 000000000..86fc1a586 --- /dev/null +++ b/src/video/ngage/SDL_ngagevideo.h @@ -0,0 +1,75 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + 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" + +#ifndef _SDL_ngagevideo_h +#define _SDL_ngagevideo_h + +#include "../SDL_sysvideo.h" + +#include +#include +#include +#include +#include // CFbsDrawDevice + +#define _THIS SDL_VideoDevice *_this + +typedef struct SDL_VideoData +{ + /* Epoc window server info */ + RWsSession NGAGE_WsSession; + RWindowGroup NGAGE_WsWindowGroup; + TInt NGAGE_WsWindowGroupID; + RWindow NGAGE_WsWindow; + CWsScreenDevice* NGAGE_WsScreen; + CWindowGc* NGAGE_WindowGc; + TRequestStatus NGAGE_WsEventStatus; + TRequestStatus NGAGE_RedrawEventStatus; + TWsEvent NGAGE_WsEvent; + //TWsRedrawEvent NGAGE_RedrawEvent; + + CFbsDrawDevice* NGAGE_DrawDevice; + + TBool NGAGE_IsWindowFocused; /* Not used yet */ + + /* Screen hardware frame buffer info */ + TBool NGAGE_HasFrameBuffer; + TInt NGAGE_BytesPerPixel; + TInt NGAGE_BytesPerScanLine; + TInt NGAGE_BytesPerScreen; + TDisplayMode NGAGE_DisplayMode; + TSize NGAGE_ScreenSize; + TUint8* NGAGE_FrameBuffer; + TPoint NGAGE_ScreenOffset; + + CFbsBitGc::TGraphicsOrientation NGAGE_ScreenOrientation; + + /* Simulate double screen height */ + //TInt NGAGE_ScreenXScaleValue; + //TInt NGAGE_ScreenYScaleValue; + +} SDL_VideoData; + +#endif /* _SDL_ngagevideo_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/ngage/SDL_ngagewindow.cpp b/src/video/ngage/SDL_ngagewindow.cpp new file mode 100644 index 000000000..5b0682b29 --- /dev/null +++ b/src/video/ngage/SDL_ngagewindow.cpp @@ -0,0 +1,129 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_NGAGE + +#include "../SDL_sysvideo.h" + +#include "SDL_ngagewindow.h" + +const TUint32 WindowClientHandle = 9210; + +void DisableKeyBlocking(_THIS); +void ConstructWindowL(_THIS); + +int +NGAGE_CreateWindow(_THIS, SDL_Window* window) +{ + NGAGE_Window* ngage_window = (NGAGE_Window*)SDL_calloc(1, sizeof(NGAGE_Window)); + + if (!ngage_window) { + return SDL_OutOfMemory(); + } + + window->driverdata = ngage_window; + + if (window->x == SDL_WINDOWPOS_UNDEFINED) { + window->x = 0; + } + + if (window->y == SDL_WINDOWPOS_UNDEFINED) { + window->y = 0; + } + + ngage_window->sdl_window = window; + + ConstructWindowL(_this); + + return 0; +} + +void +NGAGE_DestroyWindow(_THIS, SDL_Window* window) +{ + NGAGE_Window* ngage_window = (NGAGE_Window*)window->driverdata; + + if (ngage_window) { + SDL_free(ngage_window); + } + + window->driverdata = NULL; +} + +/*****************************************************************************/ +/* Internal */ +/*****************************************************************************/ + +void DisableKeyBlocking(_THIS) +{ + SDL_VideoData *phdata = (SDL_VideoData*)_this->driverdata; + TRawEvent event; + + event.Set((TRawEvent::TType) /*EDisableKeyBlock*/ 51); + phdata->NGAGE_WsSession.SimulateRawEvent(event); +} + +void ConstructWindowL(_THIS) +{ + SDL_VideoData *phdata = (SDL_VideoData*)_this->driverdata; + TInt error; + + error = phdata->NGAGE_WsSession.Connect(); + User::LeaveIfError(error); + phdata->NGAGE_WsScreen=new(ELeave) CWsScreenDevice(phdata->NGAGE_WsSession); + User::LeaveIfError(phdata->NGAGE_WsScreen->Construct()); + User::LeaveIfError(phdata->NGAGE_WsScreen->CreateContext(phdata->NGAGE_WindowGc)); + + phdata->NGAGE_WsWindowGroup=RWindowGroup(phdata->NGAGE_WsSession); + User::LeaveIfError(phdata->NGAGE_WsWindowGroup.Construct(WindowClientHandle)); + phdata->NGAGE_WsWindowGroup.SetOrdinalPosition(0); + + RProcess thisProcess; + TParse exeName; + exeName.Set(thisProcess.FileName(), NULL, NULL); + TBuf<32> winGroupName; + winGroupName.Append(0); + winGroupName.Append(0); + winGroupName.Append(0); // UID + winGroupName.Append(0); + winGroupName.Append(exeName.Name()); // Caption + winGroupName.Append(0); + winGroupName.Append(0); // DOC name + phdata->NGAGE_WsWindowGroup.SetName(winGroupName); + + phdata->NGAGE_WsWindow=RWindow(phdata->NGAGE_WsSession); + User::LeaveIfError(phdata->NGAGE_WsWindow.Construct(phdata->NGAGE_WsWindowGroup,WindowClientHandle - 1)); + phdata->NGAGE_WsWindow.SetBackgroundColor(KRgbWhite); + phdata->NGAGE_WsWindow.Activate(); + phdata->NGAGE_WsWindow.SetSize(phdata->NGAGE_WsScreen->SizeInPixels()); + phdata->NGAGE_WsWindow.SetVisible(ETrue); + + phdata->NGAGE_WsWindowGroupID = phdata->NGAGE_WsWindowGroup.Identifier(); + phdata->NGAGE_IsWindowFocused = EFalse; + + DisableKeyBlocking(_this); +} + +#endif /* SDL_VIDEO_DRIVER_NGAGE */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/ngage/SDL_ngagewindow.h b/src/video/ngage/SDL_ngagewindow.h new file mode 100644 index 000000000..148c79986 --- /dev/null +++ b/src/video/ngage/SDL_ngagewindow.h @@ -0,0 +1,45 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2022 Sam Lantinga + + 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_ngagewindow_h +#define _SDL_ngagewindow_h + +#include "../SDL_sysvideo.h" +#include "SDL_syswm.h" + +#include "SDL_ngagevideo.h" + +typedef struct { + SDL_Window* sdl_window; + +} NGAGE_Window; + + +extern int +NGAGE_CreateWindow(_THIS, SDL_Window* window); + +extern void +NGAGE_DestroyWindow(_THIS, SDL_Window* window); + +#endif /* _SDL_ngagewindow */ + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/src/video/riscos/scancodes_riscos.h b/src/video/riscos/scancodes_riscos.h index ced6b0d1b..dbba9d1a1 100644 --- a/src/video/riscos/scancodes_riscos.h +++ b/src/video/riscos/scancodes_riscos.h @@ -24,7 +24,7 @@ Sources: - https://www.riscosopen.org/wiki/documentation/show/Keyboard Scan Codes */ -/* *INDENT-OFF* */ +/* *INDENT-OFF* */ /* clang-format off */ static SDL_Scancode const riscos_scancode_table[] = { /* 0 */ SDL_SCANCODE_UNKNOWN, /* Shift */ /* 1 */ SDL_SCANCODE_UNKNOWN, /* Ctrl */ @@ -155,4 +155,4 @@ static SDL_Scancode const riscos_scancode_table[] = { /* 126 */ SDL_SCANCODE_RGUI, /* 127 */ SDL_SCANCODE_MENU }; -/* *INDENT-ON* */ +/* *INDENT-ON* */ /* clang-format on */ diff --git a/src/video/sdlgenblit.pl b/src/video/sdlgenblit.pl index c2a22b049..de07b19e5 100755 --- a/src/video/sdlgenblit.pl +++ b/src/video/sdlgenblit.pl @@ -114,7 +114,7 @@ sub open_file { #if SDL_HAVE_BLIT_AUTO -/* *INDENT-OFF* */ +/* *INDENT-OFF* */ /* clang-format off */ __EOF__ } @@ -122,7 +122,7 @@ __EOF__ sub close_file { my $name = shift; print FILE <<__EOF__; -/* *INDENT-ON* */ +/* *INDENT-ON* */ /* clang-format on */ #endif /* SDL_HAVE_BLIT_AUTO */ diff --git a/src/video/uikit/SDL_uikitopenglview.m b/src/video/uikit/SDL_uikitopenglview.m index 52158f8d7..ef5ca74e5 100644 --- a/src/video/uikit/SDL_uikitopenglview.m +++ b/src/video/uikit/SDL_uikitopenglview.m @@ -89,7 +89,7 @@ glGetIntegerv(GL_MAX_SAMPLES, &maxsamples); /* Clamp the samples to the max supported count. */ - samples = MIN(samples, maxsamples); + samples = SDL_min(samples, maxsamples); } if (sRGB) { diff --git a/src/video/uikit/SDL_uikitvideo.m b/src/video/uikit/SDL_uikitvideo.m index 5d2b96e38..81d7bf647 100644 --- a/src/video/uikit/SDL_uikitvideo.m +++ b/src/video/uikit/SDL_uikitvideo.m @@ -278,11 +278,16 @@ UIKit_ForceUpdateHomeIndicator() */ #if !defined(SDL_VIDEO_DRIVER_COCOA) -void SDL_NSLog(const char *text) +void SDL_NSLog(const char *prefix, const char *text) { @autoreleasepool { - NSString *str = [NSString stringWithUTF8String:text]; - NSLog(@"%@", str); + NSString *nsText = [NSString stringWithUTF8String:text]; + if (prefix) { + NSString *nsPrefix = [NSString stringWithUTF8String:prefix]; + NSLog(@"%@: %@", nsPrefix, nsText); + } else { + NSLog(@"%@", nsText); + } } } #endif /* SDL_VIDEO_DRIVER_COCOA */ diff --git a/src/video/uikit/SDL_uikitvulkan.m b/src/video/uikit/SDL_uikitvulkan.m index f0f2d2b04..52a1ceddb 100644 --- a/src/video/uikit/SDL_uikitvulkan.m +++ b/src/video/uikit/SDL_uikitvulkan.m @@ -51,6 +51,7 @@ int UIKit_Vulkan_LoadLibrary(_THIS, const char *path) VkExtensionProperties *extensions = NULL; Uint32 extensionCount = 0; SDL_bool hasSurfaceExtension = SDL_FALSE; + SDL_bool hasMetalSurfaceExtension = SDL_FALSE; SDL_bool hasIOSSurfaceExtension = SDL_FALSE; PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL; @@ -134,6 +135,8 @@ int UIKit_Vulkan_LoadLibrary(_THIS, const char *path) for (Uint32 i = 0; i < extensionCount; i++) { if (SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { hasSurfaceExtension = SDL_TRUE; + } else if (SDL_strcmp(VK_EXT_METAL_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { + hasMetalSurfaceExtension = SDL_TRUE; } else if (SDL_strcmp(VK_MVK_IOS_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { hasIOSSurfaceExtension = SDL_TRUE; } @@ -145,9 +148,10 @@ int UIKit_Vulkan_LoadLibrary(_THIS, const char *path) SDL_SetError("Installed Vulkan Portability doesn't implement the " VK_KHR_SURFACE_EXTENSION_NAME " extension"); goto fail; - } else if (!hasIOSSurfaceExtension) { + } else if (!hasMetalSurfaceExtension && !hasIOSSurfaceExtension) { SDL_SetError("Installed Vulkan Portability doesn't implement the " - VK_MVK_IOS_SURFACE_EXTENSION_NAME "extension"); + VK_EXT_METAL_SURFACE_EXTENSION_NAME " or " + VK_MVK_IOS_SURFACE_EXTENSION_NAME " extensions"); goto fail; } @@ -174,7 +178,7 @@ SDL_bool UIKit_Vulkan_GetInstanceExtensions(_THIS, const char **names) { static const char *const extensionsForUIKit[] = { - VK_KHR_SURFACE_EXTENSION_NAME, VK_MVK_IOS_SURFACE_EXTENSION_NAME + VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_METAL_SURFACE_EXTENSION_NAME }; if (!_this->vulkan_config.loader_handle) { SDL_SetError("Vulkan is not loaded"); @@ -193,11 +197,14 @@ SDL_bool UIKit_Vulkan_CreateSurface(_THIS, { PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr; + PFN_vkCreateMetalSurfaceEXT vkCreateMetalSurfaceEXT = + (PFN_vkCreateMetalSurfaceEXT)vkGetInstanceProcAddr( + (VkInstance)instance, + "vkCreateMetalSurfaceEXT"); PFN_vkCreateIOSSurfaceMVK vkCreateIOSSurfaceMVK = (PFN_vkCreateIOSSurfaceMVK)vkGetInstanceProcAddr( (VkInstance)instance, "vkCreateIOSSurfaceMVK"); - VkIOSSurfaceCreateInfoMVK createInfo = {}; VkResult result; SDL_MetalView metalview; @@ -206,9 +213,10 @@ SDL_bool UIKit_Vulkan_CreateSurface(_THIS, return SDL_FALSE; } - if (!vkCreateIOSSurfaceMVK) { - SDL_SetError(VK_MVK_IOS_SURFACE_EXTENSION_NAME - " extension is not enabled in the Vulkan instance."); + if (!vkCreateMetalSurfaceEXT && !vkCreateIOSSurfaceMVK) { + SDL_SetError(VK_EXT_METAL_SURFACE_EXTENSION_NAME " or " + VK_MVK_IOS_SURFACE_EXTENSION_NAME + " extensions are not enabled in the Vulkan instance."); return SDL_FALSE; } @@ -217,17 +225,34 @@ SDL_bool UIKit_Vulkan_CreateSurface(_THIS, return SDL_FALSE; } - createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK; - createInfo.pNext = NULL; - createInfo.flags = 0; - createInfo.pView = (const void *)metalview; - result = vkCreateIOSSurfaceMVK(instance, &createInfo, - NULL, surface); - if (result != VK_SUCCESS) { - UIKit_Metal_DestroyView(_this, metalview); - SDL_SetError("vkCreateIOSSurfaceMVK failed: %s", - SDL_Vulkan_GetResultString(result)); - return SDL_FALSE; + if (vkCreateMetalSurfaceEXT) { + VkMetalSurfaceCreateInfoEXT createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.pLayer = (__bridge const CAMetalLayer *) + UIKit_Metal_GetLayer(_this, metalview); + result = vkCreateMetalSurfaceEXT(instance, &createInfo, NULL, surface); + if (result != VK_SUCCESS) { + UIKit_Metal_DestroyView(_this, metalview); + SDL_SetError("vkCreateMetalSurfaceEXT failed: %s", + SDL_Vulkan_GetResultString(result)); + return SDL_FALSE; + } + } else { + VkIOSSurfaceCreateInfoMVK createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.pView = (const void *)metalview; + result = vkCreateIOSSurfaceMVK(instance, &createInfo, + NULL, surface); + if (result != VK_SUCCESS) { + UIKit_Metal_DestroyView(_this, metalview); + SDL_SetError("vkCreateIOSSurfaceMVK failed: %s", + SDL_Vulkan_GetResultString(result)); + return SDL_FALSE; + } } /* Unfortunately there's no SDL_Vulkan_DestroySurface function we can call diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index e515d9d6f..80ef3fd98 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -476,19 +476,16 @@ ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial) const uint32_t *directions_libdecor = directions; #endif - /* Hit tests shouldn't apply to xdg_popups, right? */ - SDL_assert(!WINDOW_IS_XDG_POPUP(window)); - switch (rc) { case SDL_HITTEST_DRAGGABLE: #ifdef HAVE_LIBDECOR_H - if (input->display->shell.libdecor) { + if (window_data->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) { if (window_data->shell_surface.libdecor.frame) { libdecor_frame_move(window_data->shell_surface.libdecor.frame, input->seat, serial); } } else #endif - if (input->display->shell.xdg) { + if (window_data->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL) { if (window_data->shell_surface.xdg.roleobj.toplevel) { xdg_toplevel_move(window_data->shell_surface.xdg.roleobj.toplevel, input->seat, @@ -506,13 +503,13 @@ ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial) case SDL_HITTEST_RESIZE_BOTTOMLEFT: case SDL_HITTEST_RESIZE_LEFT: #ifdef HAVE_LIBDECOR_H - if (input->display->shell.libdecor) { + if (window_data->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) { if (window_data->shell_surface.libdecor.frame) { libdecor_frame_resize(window_data->shell_surface.libdecor.frame, input->seat, serial, directions_libdecor[rc - SDL_HITTEST_RESIZE_TOPLEFT]); } } else #endif - if (input->display->shell.xdg) { + if (window_data->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL) { if (window_data->shell_surface.xdg.roleobj.toplevel) { xdg_toplevel_resize(window_data->shell_surface.xdg.roleobj.toplevel, input->seat, diff --git a/src/video/wayland/SDL_waylandsym.h b/src/video/wayland/SDL_waylandsym.h index 6891325c7..a7a5a170c 100644 --- a/src/video/wayland/SDL_waylandsym.h +++ b/src/video/wayland/SDL_waylandsym.h @@ -19,7 +19,7 @@ 3. This notice may not be removed or altered from any source distribution. */ -/* *INDENT-OFF* */ +/* *INDENT-OFF* */ /* clang-format off */ #ifndef SDL_WAYLAND_MODULE #define SDL_WAYLAND_MODULE(modname) @@ -210,6 +210,6 @@ SDL_WAYLAND_SYM(bool, libdecor_configuration_get_window_state, (struct libdecor_ #undef SDL_WAYLAND_SYM #undef SDL_WAYLAND_INTERFACE -/* *INDENT-ON* */ +/* *INDENT-ON* */ /* clang-format on */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index 0305c46a1..2992d5295 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -878,7 +878,7 @@ static const struct wl_registry_listener registry_listener = { }; #ifdef HAVE_LIBDECOR_H -static SDL_bool should_use_libdecor(SDL_VideoData *data) +static SDL_bool should_use_libdecor(SDL_VideoData *data, SDL_bool ignore_xdg) { if (!SDL_WAYLAND_HAVE_WAYLAND_LIBDECOR) { return SDL_FALSE; @@ -892,6 +892,10 @@ static SDL_bool should_use_libdecor(SDL_VideoData *data) return SDL_TRUE; } + if (ignore_xdg) { + return SDL_TRUE; + } + if (data->decoration_manager) { return SDL_FALSE; } @@ -900,6 +904,21 @@ static SDL_bool should_use_libdecor(SDL_VideoData *data) } #endif +SDL_bool +Wayland_LoadLibdecor(SDL_VideoData *data, SDL_bool ignore_xdg) +{ +#ifdef HAVE_LIBDECOR_H + if (data->shell.libdecor != NULL) { + return SDL_TRUE; /* Already loaded! */ + } + if (should_use_libdecor(data, ignore_xdg)) { + data->shell.libdecor = libdecor_new(data->display, &libdecor_interface); + return data->shell.libdecor != NULL; + } +#endif + return SDL_FALSE; +} + int Wayland_VideoInit(_THIS) { @@ -920,12 +939,8 @@ Wayland_VideoInit(_THIS) // First roundtrip to receive all registry objects. WAYLAND_wl_display_roundtrip(data->display); -#ifdef HAVE_LIBDECOR_H - /* Don't have server-side decorations? Try client-side instead. */ - if (should_use_libdecor(data)) { - data->shell.libdecor = libdecor_new(data->display, &libdecor_interface); - } -#endif + /* Now that we have all the protocols, load libdecor if applicable */ + Wayland_LoadLibdecor(data, SDL_FALSE); // Second roundtrip to receive all output events. WAYLAND_wl_display_roundtrip(data->display); diff --git a/src/video/wayland/SDL_waylandvideo.h b/src/video/wayland/SDL_waylandvideo.h index 6f941db80..9b2d6835f 100644 --- a/src/video/wayland/SDL_waylandvideo.h +++ b/src/video/wayland/SDL_waylandvideo.h @@ -122,6 +122,8 @@ extern void SDL_WAYLAND_register_output(struct wl_output *output); extern SDL_bool SDL_WAYLAND_own_surface(struct wl_surface *surface); extern SDL_bool SDL_WAYLAND_own_output(struct wl_output *output); +extern SDL_bool Wayland_LoadLibdecor(SDL_VideoData *data, SDL_bool ignore_xdg); + #endif /* SDL_waylandvideo_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index 0bbae4691..f5d598c62 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -683,6 +683,34 @@ Wayland_PopupWatch(void *data, SDL_Event *event) return 1; } +static void +handle_configure_zxdg_decoration(void *data, + struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, + uint32_t mode) +{ + SDL_Window *window = (SDL_Window *) data; + SDL_WindowData *driverdata = (SDL_WindowData *) window->driverdata; + + /* If the compositor tries to force CSD anyway, bail on direct XDG support + * and fall back to libdecor, it will handle these events from then on. + * + * To do this we have to fully unmap, then map with libdecor loaded. + */ + if (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE) { + if (!Wayland_LoadLibdecor(driverdata->waylandData, SDL_TRUE)) { + /* libdecor isn't available, so no borders for you... oh well */ + return; + } + SDL_HideWindow(window); + driverdata->shell_surface_type = WAYLAND_SURFACE_LIBDECOR; + SDL_ShowWindow(window); + } +} + +static const struct zxdg_toplevel_decoration_v1_listener decoration_listener = { + handle_configure_zxdg_decoration +}; + #ifdef HAVE_LIBDECOR_H static void decoration_frame_configure(struct libdecor_frame *frame, @@ -1258,6 +1286,9 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window) /* Create the window decorations */ if (!WINDOW_IS_XDG_POPUP(window) && data->shell_surface.xdg.roleobj.toplevel && c->decoration_manager) { data->server_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(c->decoration_manager, data->shell_surface.xdg.roleobj.toplevel); + zxdg_toplevel_decoration_v1_add_listener(data->server_decoration, + &decoration_listener, + window); } } else { /* Nothing to see here, just commit. */ @@ -1628,7 +1659,6 @@ void Wayland_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) { #ifdef HAVE_LIBDECOR_H - SDL_VideoData *data = _this->driverdata; const SDL_WindowData *wind = window->driverdata; if (WINDOW_IS_LIBDECOR(data, window)) { @@ -1874,6 +1904,22 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window) /* We may need to create an idle inhibitor for this new window */ Wayland_SuspendScreenSaver(_this); + #define IS_POPUP(window) \ + (window->flags & (SDL_WINDOW_TOOLTIP | SDL_WINDOW_POPUP_MENU)) +#ifdef HAVE_LIBDECOR_H + if (c->shell.libdecor && !IS_POPUP(window)) { + data->shell_surface_type = WAYLAND_SURFACE_LIBDECOR; + } else +#endif + if (c->shell.xdg) { + if (IS_POPUP(window)) { + data->shell_surface_type = WAYLAND_SURFACE_XDG_POPUP; + } else { + data->shell_surface_type = WAYLAND_SURFACE_XDG_TOPLEVEL; + } + } /* All other cases will be WAYLAND_SURFACE_UNKNOWN */ + #undef IS_POPUP + return 0; } diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h index b1ba98cf9..74c3c09eb 100644 --- a/src/video/wayland/SDL_waylandwindow.h +++ b/src/video/wayland/SDL_waylandwindow.h @@ -32,32 +32,11 @@ struct SDL_WaylandInput; -typedef struct { - struct xdg_surface *surface; - union { - struct xdg_toplevel *toplevel; - struct { - struct xdg_popup *popup; - struct xdg_positioner *positioner; - Uint32 parentID; - SDL_Window *child; - } popup; - } roleobj; - SDL_bool initial_configure_seen; -} SDL_xdg_shell_surface; - +/* TODO: Remove these helpers, they're from before we had shell_surface_type */ #define WINDOW_IS_XDG_POPUP(window) \ - (window->flags & (SDL_WINDOW_TOOLTIP | SDL_WINDOW_POPUP_MENU)) - -#ifdef HAVE_LIBDECOR_H -typedef struct { - struct libdecor_frame *frame; - SDL_bool initial_configure_seen; -} SDL_libdecor_surface; - -#define WINDOW_IS_LIBDECOR(viddata, window) \ - (viddata->shell.libdecor && !WINDOW_IS_XDG_POPUP(window)) -#endif + (((SDL_WindowData*) window->driverdata)->shell_surface_type == WAYLAND_SURFACE_XDG_POPUP) +#define WINDOW_IS_LIBDECOR(ignoreme, window) \ + (((SDL_WindowData*) window->driverdata)->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) typedef struct { SDL_Window *sdlwindow; @@ -66,12 +45,35 @@ typedef struct { struct wl_callback *frame_callback; struct wl_event_queue *frame_event_queue; struct wl_surface *frame_surface_wrapper; + union { #ifdef HAVE_LIBDECOR_H - SDL_libdecor_surface libdecor; + struct { + struct libdecor_frame *frame; + SDL_bool initial_configure_seen; + } libdecor; #endif - SDL_xdg_shell_surface xdg; + struct { + struct xdg_surface *surface; + union { + struct xdg_toplevel *toplevel; + struct { + struct xdg_popup *popup; + struct xdg_positioner *positioner; + Uint32 parentID; + SDL_Window *child; + } popup; + } roleobj; + SDL_bool initial_configure_seen; + } xdg; } shell_surface; + enum { + WAYLAND_SURFACE_UNKNOWN = 0, + WAYLAND_SURFACE_XDG_TOPLEVEL, + WAYLAND_SURFACE_XDG_POPUP, + WAYLAND_SURFACE_LIBDECOR + } shell_surface_type; + struct wl_egl_window *egl_window; struct SDL_WaylandInput *keyboard_device; #if SDL_VIDEO_OPENGL_EGL diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index ebd0dd1f9..084bb9a96 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -29,6 +29,7 @@ #include "SDL_timer.h" #include "SDL_vkeys.h" #include "SDL_hints.h" +#include "SDL_main.h" #include "../../events/SDL_events_c.h" #include "../../events/SDL_touch_c.h" #include "../../events/scancodes_windows.h" @@ -1370,10 +1371,15 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { SDL_Window *window = data->window; if (window->hit_test) { - POINT winpoint = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + POINT winpoint; + winpoint.x = GET_X_LPARAM(lParam); + winpoint.y = GET_Y_LPARAM(lParam); if (ScreenToClient(hwnd, &winpoint)) { - const SDL_Point point = { (int) winpoint.x, (int) winpoint.y }; - const SDL_HitTestResult rc = window->hit_test(window, &point, window->hit_test_data); + SDL_Point point; + SDL_HitTestResult rc; + point.x = winpoint.x; + point.y = winpoint.y; + rc = window->hit_test(window, &point, window->hit_test_data); switch (rc) { #define POST_HIT_TEST(ret) { SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0); return ret; } case SDL_HITTEST_DRAGGABLE: POST_HIT_TEST(HTCAPTION); diff --git a/src/video/windows/SDL_windowsvideo.c b/src/video/windows/SDL_windowsvideo.c index 4bd2a9831..93a6bfa81 100644 --- a/src/video/windows/SDL_windowsvideo.c +++ b/src/video/windows/SDL_windowsvideo.c @@ -35,6 +35,22 @@ #include "SDL_windowsshape.h" #include "SDL_windowsvulkan.h" +#ifdef D3D_DEBUG_INFO +#ifndef D3D_SDK_VERSION +#define D3D_SDK_VERSION (32 | 0x80000000) +#endif +#ifndef D3D9b_SDK_VERSION +#define D3D9b_SDK_VERSION (31 | 0x80000000) +#endif +#else /**/ +#ifndef D3D_SDK_VERSION +#define D3D_SDK_VERSION 32 +#endif +#ifndef D3D9b_SDK_VERSION +#define D3D9b_SDK_VERSION 31 +#endif +#endif + /* Initialization/Query functions */ static int WIN_VideoInit(_THIS); static void WIN_VideoQuit(_THIS); diff --git a/src/video/x11/SDL_x11dyn.c b/src/video/x11/SDL_x11dyn.c index 29a8186fa..4bfef21e3 100644 --- a/src/video/x11/SDL_x11dyn.c +++ b/src/video/x11/SDL_x11dyn.c @@ -47,9 +47,6 @@ typedef struct #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR NULL #endif -#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA NULL -#endif #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 NULL #endif @@ -62,20 +59,15 @@ typedef struct #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS NULL #endif -#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE NULL -#endif static x11dynlib x11libs[] = { {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC}, {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT}, {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR}, - {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA}, {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2}, {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES}, {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR}, - {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS}, - {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE} + {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS} }; static void * diff --git a/src/video/x11/SDL_x11dyn.h b/src/video/x11/SDL_x11dyn.h index c2678bfed..feac35fa9 100644 --- a/src/video/x11/SDL_x11dyn.h +++ b/src/video/x11/SDL_x11dyn.h @@ -52,9 +52,6 @@ #if SDL_VIDEO_DRIVER_X11_XDBE #include #endif -#if SDL_VIDEO_DRIVER_X11_XINERAMA -#include -#endif #if SDL_VIDEO_DRIVER_X11_XINPUT2 #include #endif @@ -70,9 +67,6 @@ #if SDL_VIDEO_DRIVER_X11_XSHAPE #include #endif -#if SDL_VIDEO_DRIVER_X11_XVIDMODE -#include -#endif #ifdef __cplusplus extern "C" diff --git a/src/video/x11/SDL_x11keyboard.c b/src/video/x11/SDL_x11keyboard.c index c84bcc798..9d9f3f9f0 100644 --- a/src/video/x11/SDL_x11keyboard.c +++ b/src/video/x11/SDL_x11keyboard.c @@ -37,7 +37,7 @@ #include #endif -/* *INDENT-OFF* */ +/* *INDENT-OFF* */ /* clang-format off */ static const struct { KeySym keysym; SDL_Scancode scancode; @@ -160,7 +160,7 @@ static const struct { xfree86_scancode_table2, SDL_arraysize(xfree86_scancode_table2) }, { xvnc_scancode_table, SDL_arraysize(xvnc_scancode_table) }, }; -/* *INDENT-OFF* */ +/* *INDENT-OFF* */ /* clang-format off */ /* This function only works for keyboards in US QWERTY layout */ static SDL_Scancode @@ -267,13 +267,6 @@ X11_InitKeyboard(_THIS) int best_index; int distance; Bool xkb_repeat = 0; - XKeyboardState values; - SDL_zero(values); - values.global_auto_repeat = AutoRepeatModeOff; - - X11_XGetKeyboardControl(data->display, &values); - if (values.global_auto_repeat != AutoRepeatModeOn) - X11_XAutoRepeatOn(data->display); #if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM { diff --git a/src/video/x11/SDL_x11modes.c b/src/video/x11/SDL_x11modes.c index f2cbdb45f..d740f66ae 100644 --- a/src/video/x11/SDL_x11modes.c +++ b/src/video/x11/SDL_x11modes.c @@ -148,61 +148,29 @@ X11_GetPixelFormatFromVisualInfo(Display * display, XVisualInfo * vinfo) return SDL_PIXELFORMAT_UNKNOWN; } -#if SDL_VIDEO_DRIVER_X11_XINERAMA -static SDL_bool -CheckXinerama(Display * display, int *major, int *minor) -{ - int event_base = 0; - int error_base = 0; - - /* Default the extension not available */ - *major = *minor = 0; - - /* Allow environment override */ - if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_XINERAMA, SDL_TRUE)) { -#ifdef X11MODES_DEBUG - printf("Xinerama disabled due to hint\n"); -#endif - return SDL_FALSE; - } - - if (!SDL_X11_HAVE_XINERAMA) { -#ifdef X11MODES_DEBUG - printf("Xinerama support not available\n"); -#endif - return SDL_FALSE; - } - - /* Query the extension version */ - if (!X11_XineramaQueryExtension(display, &event_base, &error_base) || - !X11_XineramaQueryVersion(display, major, minor) || - !X11_XineramaIsActive(display)) { -#ifdef X11MODES_DEBUG - printf("Xinerama not active on the display\n"); -#endif - return SDL_FALSE; - } -#ifdef X11MODES_DEBUG - printf("Xinerama available at version %d.%d!\n", *major, *minor); -#endif - return SDL_TRUE; -} - -/* !!! FIXME: remove this later. */ -/* we have a weird bug where XineramaQueryScreens() throws an X error, so this - is here to help track it down (and not crash, too!). */ -static SDL_bool xinerama_triggered_error = SDL_FALSE; static int -X11_XineramaFailed(Display * d, XErrorEvent * e) +GetXftDPI(Display* dpy) { - xinerama_triggered_error = SDL_TRUE; - fprintf(stderr, "XINERAMA X ERROR: type=%d serial=%lu err=%u req=%u minor=%u\n", - e->type, e->serial, (unsigned int) e->error_code, - (unsigned int) e->request_code, (unsigned int) e->minor_code); - fflush(stderr); - return 0; + char* xdefault_resource; + int xft_dpi, err; + + xdefault_resource = X11_XGetDefault(dpy, "Xft", "dpi"); + + if(!xdefault_resource) { + return 0; + } + + /* + * It's possible for SDL_atoi to call SDL_strtol, if it fails due to a + * overflow or an underflow, it will return LONG_MAX or LONG_MIN and set + * errno to ERANGE. So we need to check for this so we dont get crazy dpi + * values + */ + xft_dpi = SDL_atoi(xdefault_resource); + err = errno; + + return err == ERANGE ? 0 : xft_dpi; } -#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */ #if SDL_VIDEO_DRIVER_X11_XRANDR static SDL_bool @@ -345,30 +313,6 @@ SetXRandRDisplayName(Display *dpy, Atom EDID, char *name, const size_t namelen, #endif } -static int -GetXftDPI(Display* dpy) -{ - char* xdefault_resource; - int xft_dpi, err; - - xdefault_resource = X11_XGetDefault(dpy, "Xft", "dpi"); - - if(!xdefault_resource) { - return 0; - } - - /* - * It's possible for SDL_atoi to call SDL_strtol, if it fails due to a - * overflow or an underflow, it will return LONG_MAX or LONG_MIN and set - * errno to ERANGE. So we need to check for this so we dont get crazy dpi - * values - */ - xft_dpi = SDL_atoi(xdefault_resource); - err = errno; - - return err == ERANGE ? 0 : xft_dpi; -} - static int X11_InitModes_XRandR(_THIS) { @@ -506,7 +450,7 @@ X11_InitModes_XRandR(_THIS) displaydata->scanline_pad = scanline_pad; displaydata->x = display_x; displaydata->y = display_y; - displaydata->use_xrandr = 1; + displaydata->use_xrandr = SDL_TRUE; displaydata->xrandr_output = res->outputs[output]; SetXRandRModeInfo(dpy, res, output_crtc, modeID, &mode); @@ -534,343 +478,124 @@ X11_InitModes_XRandR(_THIS) } #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ -#if SDL_VIDEO_DRIVER_X11_XVIDMODE -static SDL_bool -CheckVidMode(Display * display, int *major, int *minor) +/* This is used if there's no better functionality--like XRandR--to use. + It won't attempt to supply different display modes at all, but it can + enumerate the current displays and their current sizes. */ +static int X11_InitModes_StdXlib(_THIS) { - int vm_event, vm_error = -1; - /* Default the extension not available */ - *major = *minor = 0; + /* !!! FIXME: a lot of copy/paste from X11_InitModes_XRandR in this function. */ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + Display *dpy = data->display; + const int default_screen = DefaultScreen(dpy); + Screen *screen = ScreenOfDisplay(dpy, default_screen); + int display_mm_width, display_mm_height, xft_dpi, scanline_pad, n, i; + SDL_DisplayModeData *modedata; + SDL_DisplayData *displaydata; + SDL_DisplayMode mode; + XPixmapFormatValues *pixmapformats; + Uint32 pixelformat; + XVisualInfo vinfo; + SDL_VideoDisplay display; - /* Allow environment override */ - if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_XVIDMODE, SDL_TRUE)) { -#ifdef X11MODES_DEBUG - printf("XVidMode disabled due to hint\n"); -#endif - return SDL_FALSE; + /* note that generally even if you have a multiple physical monitors, ScreenCount(dpy) still only reports ONE screen. */ + + if (get_visualinfo(dpy, default_screen, &vinfo) < 0) { + return SDL_SetError("Failed to find an X11 visual for the primary display"); } - if (!SDL_X11_HAVE_XVIDMODE) { -#ifdef X11MODES_DEBUG - printf("XVidMode support not available\n"); -#endif - return SDL_FALSE; + pixelformat = X11_GetPixelFormatFromVisualInfo(dpy, &vinfo); + if (SDL_ISPIXELFORMAT_INDEXED(pixelformat)) { + return SDL_SetError("Palettized video modes are no longer supported"); } - /* Query the extension version */ - if (!X11_XF86VidModeQueryExtension(display, &vm_event, &vm_error) - || !X11_XF86VidModeQueryVersion(display, major, minor)) { -#ifdef X11MODES_DEBUG - printf("XVidMode not active on the display\n"); -#endif - return SDL_FALSE; + SDL_zero(mode); + mode.w = WidthOfScreen(screen); + mode.h = HeightOfScreen(screen); + mode.format = pixelformat; + mode.refresh_rate = 0; /* don't know it, sorry. */ + + displaydata = (SDL_DisplayData *) SDL_calloc(1, sizeof(*displaydata)); + if (!displaydata) { + return SDL_OutOfMemory(); } -#ifdef X11MODES_DEBUG - printf("XVidMode available at version %d.%d!\n", *major, *minor); -#endif - return SDL_TRUE; + + modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData)); + if (!modedata) { + SDL_free(displaydata); + return SDL_OutOfMemory(); + } + mode.driverdata = modedata; + + display_mm_width = WidthMMOfScreen(screen); + display_mm_height = HeightMMOfScreen(screen); + + displaydata->screen = default_screen; + displaydata->visual = vinfo.visual; + displaydata->depth = vinfo.depth; + displaydata->hdpi = display_mm_width ? (((float) mode.w) * 25.4f / display_mm_width) : 0.0f; + displaydata->vdpi = display_mm_height ? (((float) mode.h) * 25.4f / display_mm_height) : 0.0f; + displaydata->ddpi = SDL_ComputeDiagonalDPI(mode.w, mode.h, ((float) display_mm_width) / 25.4f,((float) display_mm_height) / 25.4f); + + xft_dpi = GetXftDPI(dpy); + if(xft_dpi > 0) { + displaydata->hdpi = (float)xft_dpi; + displaydata->vdpi = (float)xft_dpi; + } + + scanline_pad = SDL_BYTESPERPIXEL(pixelformat) * 8; + pixmapformats = X11_XListPixmapFormats(dpy, &n); + if (pixmapformats) { + for (i = 0; i < n; ++i) { + if (pixmapformats[i].depth == vinfo.depth) { + scanline_pad = pixmapformats[i].scanline_pad; + break; + } + } + X11_XFree(pixmapformats); + } + + displaydata->scanline_pad = scanline_pad; + displaydata->x = 0; + displaydata->y = 0; + displaydata->use_xrandr = SDL_FALSE; + + SDL_zero(display); + display.name = (char *) "Generic X11 Display"; /* this is just copied and thrown away, it's safe to cast to char* here. */ + display.desktop_mode = mode; + display.current_mode = mode; + display.driverdata = displaydata; + SDL_AddVideoDisplay(&display, SDL_FALSE); + + return 0; } -static -Bool XF86VidModeGetModeInfo(Display * dpy, int scr, - XF86VidModeModeInfo* info) -{ - Bool retval; - int dotclock; - XF86VidModeModeLine l; - SDL_zerop(info); - SDL_zero(l); - retval = X11_XF86VidModeGetModeLine(dpy, scr, &dotclock, &l); - info->dotclock = dotclock; - info->hdisplay = l.hdisplay; - info->hsyncstart = l.hsyncstart; - info->hsyncend = l.hsyncend; - info->htotal = l.htotal; - info->hskew = l.hskew; - info->vdisplay = l.vdisplay; - info->vsyncstart = l.vsyncstart; - info->vsyncend = l.vsyncend; - info->vtotal = l.vtotal; - info->flags = l.flags; - info->privsize = l.privsize; - info->private = l.private; - return retval; -} - -static int -CalculateXVidModeRefreshRate(const XF86VidModeModeInfo * info) -{ - return (info->htotal - && info->vtotal) ? (1000 * info->dotclock / (info->htotal * - info->vtotal)) : 0; -} - -static SDL_bool -SetXVidModeModeInfo(const XF86VidModeModeInfo *info, SDL_DisplayMode *mode) -{ - mode->w = info->hdisplay; - mode->h = info->vdisplay; - mode->refresh_rate = CalculateXVidModeRefreshRate(info); - ((SDL_DisplayModeData*)mode->driverdata)->vm_mode = *info; - return SDL_TRUE; -} -#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */ int X11_InitModes(_THIS) { - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; - int snum, screen, screencount = 0; -#if SDL_VIDEO_DRIVER_X11_XINERAMA - int xinerama_major, xinerama_minor; - int use_xinerama = 0; - XineramaScreenInfo *xinerama = NULL; -#endif + /* XRandR is the One True Modern Way to do this on X11. If this + fails, we just won't report any display modes except the current + desktop size. */ #if SDL_VIDEO_DRIVER_X11_XRANDR - int xrandr_major, xrandr_minor; -#endif -#if SDL_VIDEO_DRIVER_X11_XVIDMODE - int vm_major, vm_minor; - int use_vidmode = 0; -#endif - -/* XRandR is the One True Modern Way to do this on X11. If it's enabled and - available, don't even look at other ways of doing things. */ -#if SDL_VIDEO_DRIVER_X11_XRANDR - /* require at least XRandR v1.3 */ - if (CheckXRandR(data->display, &xrandr_major, &xrandr_minor) && - (xrandr_major >= 2 || (xrandr_major == 1 && xrandr_minor >= 3))) { - if (X11_InitModes_XRandR(_this) == 0) - return 0; + { + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + int xrandr_major, xrandr_minor; + /* require at least XRandR v1.3 */ + if (CheckXRandR(data->display, &xrandr_major, &xrandr_minor) && + (xrandr_major >= 2 || (xrandr_major == 1 && xrandr_minor >= 3))) { + return X11_InitModes_XRandR(_this); + } } #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ -/* !!! FIXME: eventually remove support for Xinerama and XVidMode (everything below here). */ - - /* This is a workaround for some apps (UnrealEngine4, for example) until - we sort out the ramifications of removing XVidMode support outright. - This block should be removed with the XVidMode support. */ - { - if (SDL_GetHintBoolean("SDL_VIDEO_X11_REQUIRE_XRANDR", SDL_FALSE)) { - #if SDL_VIDEO_DRIVER_X11_XRANDR - return SDL_SetError("XRandR support is required but not available"); - #else - return SDL_SetError("XRandR support is required but not built into SDL!"); - #endif - } - } - -#if SDL_VIDEO_DRIVER_X11_XINERAMA - /* Query Xinerama extention - * NOTE: This works with Nvidia Twinview correctly, but you need version 302.17 (released on June 2012) - * or newer of the Nvidia binary drivers - */ - if (CheckXinerama(data->display, &xinerama_major, &xinerama_minor)) { - int (*handler) (Display *, XErrorEvent *); - X11_XSync(data->display, False); - handler = X11_XSetErrorHandler(X11_XineramaFailed); - xinerama = X11_XineramaQueryScreens(data->display, &screencount); - X11_XSync(data->display, False); - X11_XSetErrorHandler(handler); - if (xinerama_triggered_error) { - xinerama = 0; - } - if (xinerama) { - use_xinerama = xinerama_major * 100 + xinerama_minor; - } - } - if (!xinerama) { - screencount = ScreenCount(data->display); - } -#else - screencount = ScreenCount(data->display); -#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */ - -#if SDL_VIDEO_DRIVER_X11_XVIDMODE - if (CheckVidMode(data->display, &vm_major, &vm_minor)) { - use_vidmode = vm_major * 100 + vm_minor; - } -#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */ - - for (snum = 0; snum < screencount; ++snum) { - XVisualInfo vinfo; - SDL_VideoDisplay display; - SDL_DisplayData *displaydata; - SDL_DisplayMode mode; - SDL_DisplayModeData *modedata; - XPixmapFormatValues *pixmapFormats; - char display_name[128]; - int i, n; - - /* Re-order screens to always put default screen first */ - if (snum == 0) { - screen = DefaultScreen(data->display); - } else if (snum == DefaultScreen(data->display)) { - screen = 0; - } else { - screen = snum; - } - -#if SDL_VIDEO_DRIVER_X11_XINERAMA - if (xinerama) { - if (get_visualinfo(data->display, 0, &vinfo) < 0) { - continue; - } - } else { - if (get_visualinfo(data->display, screen, &vinfo) < 0) { - continue; - } - } -#else - if (get_visualinfo(data->display, screen, &vinfo) < 0) { - continue; - } -#endif - - displaydata = (SDL_DisplayData *) SDL_calloc(1, sizeof(*displaydata)); - if (!displaydata) { - continue; - } - display_name[0] = '\0'; - - mode.format = X11_GetPixelFormatFromVisualInfo(data->display, &vinfo); - if (SDL_ISPIXELFORMAT_INDEXED(mode.format)) { - /* We don't support palettized modes now */ - SDL_free(displaydata); - continue; - } -#if SDL_VIDEO_DRIVER_X11_XINERAMA - if (xinerama) { - mode.w = xinerama[screen].width; - mode.h = xinerama[screen].height; - } else { - mode.w = DisplayWidth(data->display, screen); - mode.h = DisplayHeight(data->display, screen); - } -#else - mode.w = DisplayWidth(data->display, screen); - mode.h = DisplayHeight(data->display, screen); -#endif - mode.refresh_rate = 0; - - modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData)); - if (!modedata) { - SDL_free(displaydata); - continue; - } - mode.driverdata = modedata; - -#if SDL_VIDEO_DRIVER_X11_XINERAMA - /* Most of SDL's calls to X11 are unwaware of Xinerama, and to X11 standard calls, when Xinerama is active, - * there's only one screen available. So we force the screen number to zero and - * let Xinerama specific code handle specific functionality using displaydata->xinerama_info - */ - if (use_xinerama) { - displaydata->screen = 0; - displaydata->use_xinerama = use_xinerama; - displaydata->xinerama_info = xinerama[screen]; - displaydata->xinerama_screen = screen; - } - else displaydata->screen = screen; -#else - displaydata->screen = screen; -#endif - displaydata->visual = vinfo.visual; - displaydata->depth = vinfo.depth; - - /* We use the displaydata screen index here so that this works - for both the Xinerama case, where we get the overall DPI, - and the regular X11 screen info case. */ - displaydata->hdpi = (float)DisplayWidth(data->display, displaydata->screen) * 25.4f / - DisplayWidthMM(data->display, displaydata->screen); - displaydata->vdpi = (float)DisplayHeight(data->display, displaydata->screen) * 25.4f / - DisplayHeightMM(data->display, displaydata->screen); - displaydata->ddpi = SDL_ComputeDiagonalDPI(DisplayWidth(data->display, displaydata->screen), - DisplayHeight(data->display, displaydata->screen), - (float)DisplayWidthMM(data->display, displaydata->screen) / 25.4f, - (float)DisplayHeightMM(data->display, displaydata->screen) / 25.4f); - - displaydata->scanline_pad = SDL_BYTESPERPIXEL(mode.format) * 8; - pixmapFormats = X11_XListPixmapFormats(data->display, &n); - if (pixmapFormats) { - for (i = 0; i < n; ++i) { - if (pixmapFormats[i].depth == displaydata->depth) { - displaydata->scanline_pad = pixmapFormats[i].scanline_pad; - break; - } - } - X11_XFree(pixmapFormats); - } - -#if SDL_VIDEO_DRIVER_X11_XINERAMA - if (use_xinerama) { - displaydata->x = xinerama[screen].x_org; - displaydata->y = xinerama[screen].y_org; - } - else -#endif - { - displaydata->x = 0; - displaydata->y = 0; - } - -#if SDL_VIDEO_DRIVER_X11_XVIDMODE - if (!displaydata->use_xrandr && -#if SDL_VIDEO_DRIVER_X11_XINERAMA - /* XVidMode only works on the screen at the origin */ - (!displaydata->use_xinerama || - (displaydata->x == 0 && displaydata->y == 0)) && -#endif - use_vidmode) { - displaydata->use_vidmode = use_vidmode; - if (displaydata->use_xinerama) { - displaydata->vidmode_screen = 0; - } else { - displaydata->vidmode_screen = screen; - } - XF86VidModeGetModeInfo(data->display, displaydata->vidmode_screen, &modedata->vm_mode); - } -#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */ - - SDL_zero(display); - if (*display_name) { - display.name = display_name; - } - display.desktop_mode = mode; - display.current_mode = mode; - display.driverdata = displaydata; - SDL_AddVideoDisplay(&display, SDL_FALSE); - } - -#if SDL_VIDEO_DRIVER_X11_XINERAMA - if (xinerama) X11_XFree(xinerama); -#endif - - if (_this->num_displays == 0) { - return SDL_SetError("No available displays"); - } - -#if SDL_VIDEO_DRIVER_X11_XVIDMODE - if (use_vidmode) { /* we intend to remove support for XVidMode soon. */ - SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "SDL is using XVidMode to manage your displays!"); - SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "This almost always means either SDL was misbuilt"); - SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "or your X server is insufficient. Please check your setup!"); - SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Fullscreen and/or multiple displays will not work well."); - } -#endif - - return 0; + /* still here? Just set up an extremely basic display. */ + return X11_InitModes_StdXlib(_this); } void X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display) { - Display *display = ((SDL_VideoData *) _this->driverdata)->display; SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata; -#if SDL_VIDEO_DRIVER_X11_XVIDMODE - int nmodes; - XF86VidModeModeInfo ** modes; -#endif SDL_DisplayMode mode; /* Unfortunately X11 requires the window to be created with the correct @@ -882,54 +607,9 @@ X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display) mode.format = sdl_display->current_mode.format; mode.driverdata = NULL; -#if SDL_VIDEO_DRIVER_X11_XINERAMA - if (data->use_xinerama) { - int screen_w; - int screen_h; - - screen_w = DisplayWidth(display, data->screen); - screen_h = DisplayHeight(display, data->screen); - - if (data->use_vidmode && !data->xinerama_info.x_org && !data->xinerama_info.y_org && - (screen_w > data->xinerama_info.width || screen_h > data->xinerama_info.height)) { - SDL_DisplayModeData *modedata; - /* Add the full (both screens combined) xinerama mode only on the display that starts at 0,0 - * if we're using vidmode. - */ - mode.w = screen_w; - mode.h = screen_h; - mode.refresh_rate = 0; - modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData)); - if (modedata) { - *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata; - } - mode.driverdata = modedata; - if (!SDL_AddDisplayMode(sdl_display, &mode)) { - SDL_free(modedata); - } - } - else if (!data->use_xrandr) - { - SDL_DisplayModeData *modedata; - /* Add the current mode of each monitor otherwise if we can't get them from xrandr */ - mode.w = data->xinerama_info.width; - mode.h = data->xinerama_info.height; - mode.refresh_rate = 0; - modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData)); - if (modedata) { - *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata; - } - mode.driverdata = modedata; - if (!SDL_AddDisplayMode(sdl_display, &mode)) { - SDL_free(modedata); - } - } - - } -#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */ - #if SDL_VIDEO_DRIVER_X11_XRANDR if (data->use_xrandr) { + Display *display = ((SDL_VideoData *) _this->driverdata)->display; XRRScreenResources *res; res = X11_XRRGetScreenResources (display, RootWindow(display, data->screen)); @@ -960,37 +640,7 @@ X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display) } #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ -#if SDL_VIDEO_DRIVER_X11_XVIDMODE - if (data->use_vidmode && - X11_XF86VidModeGetAllModeLines(display, data->vidmode_screen, &nmodes, &modes)) { - int i; - SDL_DisplayModeData *modedata; - -#ifdef X11MODES_DEBUG - printf("VidMode modes: (unsorted)\n"); - for (i = 0; i < nmodes; ++i) { - printf("Mode %d: %d x %d @ %d, flags: 0x%x\n", i, - modes[i]->hdisplay, modes[i]->vdisplay, - CalculateXVidModeRefreshRate(modes[i]), modes[i]->flags); - } -#endif - for (i = 0; i < nmodes; ++i) { - modedata = (SDL_DisplayModeData *) SDL_calloc(1, sizeof(SDL_DisplayModeData)); - if (!modedata) { - continue; - } - mode.driverdata = modedata; - - if (!SetXVidModeModeInfo(modes[i], &mode) || !SDL_AddDisplayMode(sdl_display, &mode)) { - SDL_free(modedata); - } - } - X11_XFree(modes); - return; - } -#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */ - - if (!data->use_xrandr && !data->use_vidmode) { + if (!data->use_xrandr) { SDL_DisplayModeData *modedata; /* Add the desktop mode */ mode = sdl_display->desktop_mode; @@ -1005,6 +655,7 @@ X11_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display) } } +#if SDL_VIDEO_DRIVER_X11_XRANDR /* This catches an error from XRRSetScreenSize, as a workaround for now. */ /* !!! FIXME: remove this later when we have a better solution. */ static int (*PreXRRSetScreenSizeErrorHandler)(Display *, XErrorEvent *) = NULL; @@ -1019,20 +670,21 @@ SDL_XRRSetScreenSizeErrHandler(Display *d, XErrorEvent *e) return PreXRRSetScreenSizeErrorHandler(d, e); } +#endif int X11_SetDisplayMode(_THIS, SDL_VideoDisplay * sdl_display, SDL_DisplayMode * mode) { SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; - Display *display = viddata->display; SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata; - SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata; - int mm_width, mm_height; viddata->last_mode_change_deadline = SDL_GetTicks() + (PENDING_FOCUS_TIME * 2); #if SDL_VIDEO_DRIVER_X11_XRANDR if (data->use_xrandr) { + Display *display = viddata->display; + SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata; + int mm_width, mm_height; XRRScreenResources *res; XRROutputInfo *output_info; XRRCrtcInfo *crtc; @@ -1105,12 +757,6 @@ freeInfo: } #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ -#if SDL_VIDEO_DRIVER_X11_XVIDMODE - if (data->use_vidmode) { - X11_XF86VidModeSwitchToMode(display, data->vidmode_screen, &modedata->vm_mode); - } -#endif /* SDL_VIDEO_DRIVER_X11_XVIDMODE */ - return 0; } @@ -1129,19 +775,6 @@ X11_GetDisplayBounds(_THIS, SDL_VideoDisplay * sdl_display, SDL_Rect * rect) rect->w = sdl_display->current_mode.w; rect->h = sdl_display->current_mode.h; -#if SDL_VIDEO_DRIVER_X11_XINERAMA - /* Get the real current bounds of the display */ - if (data->use_xinerama) { - Display *display = ((SDL_VideoData *) _this->driverdata)->display; - int screencount; - XineramaScreenInfo *xinerama = X11_XineramaQueryScreens(display, &screencount); - if (xinerama) { - rect->x = xinerama[data->xinerama_screen].x_org; - rect->y = xinerama[data->xinerama_screen].y_org; - X11_XFree(xinerama); - } - } -#endif /* SDL_VIDEO_DRIVER_X11_XINERAMA */ return 0; } diff --git a/src/video/x11/SDL_x11modes.h b/src/video/x11/SDL_x11modes.h index 554868016..b599e3723 100644 --- a/src/video/x11/SDL_x11modes.h +++ b/src/video/x11/SDL_x11modes.h @@ -35,35 +35,20 @@ typedef struct float hdpi; float vdpi; - int use_xinerama; - int use_xrandr; - int use_vidmode; - -#if SDL_VIDEO_DRIVER_X11_XINERAMA - XineramaScreenInfo xinerama_info; - int xinerama_screen; -#endif + SDL_bool use_xrandr; #if SDL_VIDEO_DRIVER_X11_XRANDR RROutput xrandr_output; #endif - -#if SDL_VIDEO_DRIVER_X11_XVIDMODE - int vidmode_screen; -#endif - } SDL_DisplayData; typedef struct { #if SDL_VIDEO_DRIVER_X11_XRANDR RRMode xrandr_mode; +#else + int unused; /* just so struct isn't empty. */ #endif - -#if SDL_VIDEO_DRIVER_X11_XVIDMODE - XF86VidModeModeInfo vm_mode; -#endif - } SDL_DisplayModeData; extern int X11_InitModes(_THIS); diff --git a/src/video/x11/SDL_x11mouse.c b/src/video/x11/SDL_x11mouse.c index 9eb1ddd30..ed29288c6 100644 --- a/src/video/x11/SDL_x11mouse.c +++ b/src/video/x11/SDL_x11mouse.c @@ -244,8 +244,8 @@ X11_CreateSystemCursor(SDL_SystemCursor id) case SDL_SYSTEM_CURSOR_WAIT: shape = XC_watch; break; case SDL_SYSTEM_CURSOR_CROSSHAIR: shape = XC_tcross; break; case SDL_SYSTEM_CURSOR_WAITARROW: shape = XC_watch; break; - case SDL_SYSTEM_CURSOR_SIZENWSE: shape = XC_fleur; break; - case SDL_SYSTEM_CURSOR_SIZENESW: shape = XC_fleur; break; + case SDL_SYSTEM_CURSOR_SIZENWSE: shape = XC_top_left_corner; break; + case SDL_SYSTEM_CURSOR_SIZENESW: shape = XC_top_right_corner; break; case SDL_SYSTEM_CURSOR_SIZEWE: shape = XC_sb_h_double_arrow; break; case SDL_SYSTEM_CURSOR_SIZENS: shape = XC_sb_v_double_arrow; break; case SDL_SYSTEM_CURSOR_SIZEALL: shape = XC_fleur; break; @@ -406,6 +406,8 @@ X11_GetGlobalMouseState(int *x, int *y) buttons |= (mask & Button1Mask) ? SDL_BUTTON_LMASK : 0; buttons |= (mask & Button2Mask) ? SDL_BUTTON_MMASK : 0; buttons |= (mask & Button3Mask) ? SDL_BUTTON_RMASK : 0; + /* Use the SDL state for the extended buttons - it's better than nothing */ + buttons |= (SDL_GetMouseState(NULL, NULL) & (SDL_BUTTON_X1MASK|SDL_BUTTON_X2MASK)); /* SDL_DisplayData->x,y point to screen origin, and adding them to mouse coordinates relative to root window doesn't do the right thing * (observed on dual monitor setup with primary display being the rightmost one - mouse was offset to the right). * diff --git a/src/video/x11/SDL_x11sym.h b/src/video/x11/SDL_x11sym.h index 762a86596..3d22d2f9f 100644 --- a/src/video/x11/SDL_x11sym.h +++ b/src/video/x11/SDL_x11sym.h @@ -19,7 +19,7 @@ 3. This notice may not be removed or altered from any source distribution. */ -/* *INDENT-OFF* */ +/* *INDENT-OFF* */ /* clang-format off */ #ifndef SDL_X11_MODULE #define SDL_X11_MODULE(modname) @@ -33,8 +33,6 @@ SDL_X11_MODULE(BASEXLIB) SDL_X11_SYM(XSizeHints*,XAllocSizeHints,(void),(),return) SDL_X11_SYM(XWMHints*,XAllocWMHints,(void),(),return) SDL_X11_SYM(XClassHint*,XAllocClassHint,(void),(),return) -SDL_X11_SYM(int,XAutoRepeatOn,(Display* a),(a),return) -SDL_X11_SYM(int,XAutoRepeatOff,(Display* a),(a),return) SDL_X11_SYM(int,XChangePointerControl,(Display* a,Bool b,Bool c,int d,int e,int f),(a,b,c,d,e,f),return) SDL_X11_SYM(int,XChangeProperty,(Display* a,Window b,Atom c,Atom d,int e,int f,_Xconst unsigned char* g,int h),(a,b,c,d,e,f,g,h),return) SDL_X11_SYM(Bool,XCheckIfEvent,(Display* a,XEvent *b,Bool (*c)(Display*,XEvent*,XPointer),XPointer d),(a,b,c,d),return) @@ -72,7 +70,6 @@ SDL_X11_SYM(char*,XGetAtomName,(Display *a,Atom b),(a,b),return) SDL_X11_SYM(int,XGetInputFocus,(Display *a,Window *b,int *c),(a,b,c),return) SDL_X11_SYM(int,XGetErrorDatabaseText,(Display* a,_Xconst char* b,_Xconst char* c,_Xconst char* d,char* e,int f),(a,b,c,d,e,f),return) SDL_X11_SYM(XModifierKeymap*,XGetModifierMapping,(Display* a),(a),return) -SDL_X11_SYM(int,XGetKeyboardControl,(Display* a, XKeyboardState* b),(a,b),return) SDL_X11_SYM(int,XGetPointerControl,(Display* a,int* b,int* c,int* d),(a,b,c,d),return) SDL_X11_SYM(Window,XGetSelectionOwner,(Display* a,Atom b),(a,b),return) SDL_X11_SYM(XVisualInfo*,XGetVisualInfo,(Display* a,long b,XVisualInfo* c,int* d),(a,b,c,d),return) @@ -263,15 +260,6 @@ SDL_X11_SYM(void,XdbeFreeVisualInfo,(XdbeScreenVisualInfo *visual_info),(visual_ SDL_X11_SYM(XdbeBackBufferAttributes*,XdbeGetBackBufferAttributes,(Display *dpy,XdbeBackBuffer buffer),(dpy,buffer),return) #endif -/* Xinerama support */ -#if SDL_VIDEO_DRIVER_X11_XINERAMA -SDL_X11_MODULE(XINERAMA) -SDL_X11_SYM(Bool,XineramaIsActive,(Display *a),(a),return) -SDL_X11_SYM(Bool,XineramaQueryExtension,(Display *a,int *b,int *c),(a,b,c),return) -SDL_X11_SYM(Status,XineramaQueryVersion,(Display *a,int *b,int *c),(a,b,c),return) -SDL_X11_SYM(XineramaScreenInfo*,XineramaQueryScreens,(Display *a, int *b),(a,b),return) -#endif - /* XInput2 support for multiple mice, tablets, etc. */ #if SDL_VIDEO_DRIVER_X11_XINPUT2 SDL_X11_MODULE(XINPUT2) @@ -324,20 +312,9 @@ SDL_X11_MODULE(XSHAPE) SDL_X11_SYM(void,XShapeCombineMask,(Display *dpy,Window dest,int dest_kind,int x_off,int y_off,Pixmap src,int op),(dpy,dest,dest_kind,x_off,y_off,src,op),) #endif -#if SDL_VIDEO_DRIVER_X11_XVIDMODE -SDL_X11_MODULE(XVIDMODE) -SDL_X11_SYM(Bool,XF86VidModeGetAllModeLines,(Display *a,int b,int *c,XF86VidModeModeInfo ***d),(a,b,c,d),return) -SDL_X11_SYM(Bool,XF86VidModeGetModeLine,(Display *a,int b,int *c,XF86VidModeModeLine *d),(a,b,c,d),return) -SDL_X11_SYM(Bool,XF86VidModeGetViewPort,(Display *a,int b,int *c,int *d),(a,b,c,d),return) -SDL_X11_SYM(Bool,XF86VidModeQueryExtension,(Display *a,int *b,int *c),(a,b,c),return) -SDL_X11_SYM(Bool,XF86VidModeQueryVersion,(Display *a,int *b,int *c),(a,b,c),return) -SDL_X11_SYM(Bool,XF86VidModeSwitchToMode,(Display *a,int b,XF86VidModeModeInfo *c),(a,b,c),return) -SDL_X11_SYM(Bool,XF86VidModeLockModeSwitch,(Display *a,int b,int c),(a,b,c),return) -#endif - #undef SDL_X11_MODULE #undef SDL_X11_SYM -/* *INDENT-ON* */ +/* *INDENT-ON* */ /* clang-format on */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/x11/SDL_x11video.h b/src/video/x11/SDL_x11video.h index 8c7eb09ec..29014735c 100644 --- a/src/video/x11/SDL_x11video.h +++ b/src/video/x11/SDL_x11video.h @@ -37,9 +37,6 @@ #if SDL_VIDEO_DRIVER_X11_XDBE #include #endif -#if SDL_VIDEO_DRIVER_X11_XINERAMA -#include -#endif #if SDL_VIDEO_DRIVER_X11_XINPUT2 #include #endif @@ -52,9 +49,6 @@ #if SDL_VIDEO_DRIVER_X11_XSHAPE #include #endif -#if SDL_VIDEO_DRIVER_X11_XVIDMODE -#include -#endif #include "../../core/linux/SDL_dbus.h" #include "../../core/linux/SDL_ime.h" diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index 3c78beaa5..07fb60266 100644 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -73,13 +73,6 @@ X11_XIfEventTimeout(Display *display, XEvent *event_return, Bool (*predicate)(), } */ -static SDL_bool -X11_IsWindowLegacyFullscreen(_THIS, SDL_Window * window) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - return (data->fswindow != 0); -} - static SDL_bool X11_IsWindowMapped(_THIS, SDL_Window * window) { @@ -1441,161 +1434,12 @@ X11_SetWindowFullscreenViaWM(_THIS, SDL_Window * window, SDL_VideoDisplay * _dis X11_XFlush(display); } -/* This handles fullscreen itself, outside the Window Manager. */ -static void -X11_BeginWindowFullscreenLegacy(_THIS, SDL_Window * window, SDL_VideoDisplay * _display) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata; - Visual *visual = data->visual; - Display *display = data->videodata->display; - const int screen = displaydata->screen; - Window root = RootWindow(display, screen); - const int def_vis = (visual == DefaultVisual(display, screen)); - unsigned long xattrmask = 0; - XSetWindowAttributes xattr; - XEvent ev; - SDL_Rect rect; - - if ( data->fswindow ) { - return; /* already fullscreen, I hope. */ - } - - X11_GetDisplayBounds(_this, _display, &rect); - - SDL_zero(xattr); - xattr.override_redirect = True; - xattrmask |= CWOverrideRedirect; - xattr.background_pixel = def_vis ? BlackPixel(display, screen) : 0; - xattrmask |= CWBackPixel; - xattr.border_pixel = 0; - xattrmask |= CWBorderPixel; - xattr.colormap = data->colormap; - xattrmask |= CWColormap; - - data->fswindow = X11_XCreateWindow(display, root, - rect.x, rect.y, rect.w, rect.h, 0, - displaydata->depth, InputOutput, - visual, xattrmask, &xattr); - - X11_XSelectInput(display, data->fswindow, StructureNotifyMask); - X11_XSetWindowBackground(display, data->fswindow, 0); - X11_XInstallColormap(display, data->colormap); - X11_XClearWindow(display, data->fswindow); - X11_XMapRaised(display, data->fswindow); - - /* Make sure the fswindow is in view by warping mouse to the corner */ - X11_XUngrabPointer(display, CurrentTime); - X11_XWarpPointer(display, None, root, 0, 0, 0, 0, rect.x, rect.y); - - /* Wait to be mapped, filter Unmap event out if it arrives. */ - X11_XIfEvent(display, &ev, &isMapNotify, (XPointer)&data->fswindow); - X11_XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->fswindow); - -#if SDL_VIDEO_DRIVER_X11_XVIDMODE - if ( displaydata->use_vidmode ) { - X11_XF86VidModeLockModeSwitch(display, screen, True); - } -#endif - - SetWindowBordered(display, displaydata->screen, data->xwindow, SDL_FALSE); - - /* Center actual window within our cover-the-screen window. */ - X11_XReparentWindow(display, data->xwindow, data->fswindow, - (rect.w - window->w) / 2, (rect.h - window->h) / 2); - - /* Move the mouse to the upper left to make sure it's on-screen */ - X11_XWarpPointer(display, None, root, 0, 0, 0, 0, rect.x, rect.y); - - /* Center mouse in the fullscreen window. */ - rect.x += (rect.w / 2); - rect.y += (rect.h / 2); - X11_XWarpPointer(display, None, root, 0, 0, 0, 0, rect.x, rect.y); - - /* Wait to be mapped, filter Unmap event out if it arrives. */ - X11_XIfEvent(display, &ev, &isMapNotify, (XPointer)&data->xwindow); - X11_XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->xwindow); - - SDL_UpdateWindowGrab(window); -} - -static void -X11_EndWindowFullscreenLegacy(_THIS, SDL_Window * window, SDL_VideoDisplay * _display) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata; - Display *display = data->videodata->display; - const int screen = displaydata->screen; - Window root = RootWindow(display, screen); - Window fswindow = data->fswindow; - XEvent ev; - - if (!data->fswindow) { - return; /* already not fullscreen, I hope. */ - } - - data->fswindow = None; - -#if SDL_VIDEO_DRIVER_X11_VIDMODE - if ( displaydata->use_vidmode ) { - X11_XF86VidModeLockModeSwitch(display, screen, False); - } -#endif - - SDL_UpdateWindowGrab(window); - - X11_XReparentWindow(display, data->xwindow, root, window->x, window->y); - - /* flush these events so they don't confuse normal event handling */ - X11_XSync(display, False); - X11_XCheckIfEvent(display, &ev, &isMapNotify, (XPointer)&data->xwindow); - X11_XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->xwindow); - - SetWindowBordered(display, screen, data->xwindow, - (window->flags & SDL_WINDOW_BORDERLESS) == 0); - - X11_XWithdrawWindow(display, fswindow, screen); - - /* Wait to be unmapped. */ - X11_XIfEvent(display, &ev, &isUnmapNotify, (XPointer)&fswindow); - X11_XDestroyWindow(display, fswindow); -} - - void X11_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen) { - /* !!! FIXME: SDL_Hint? */ - SDL_bool legacy = SDL_FALSE; - const char *env = SDL_getenv("SDL_VIDEO_X11_LEGACY_FULLSCREEN"); - if (env) { - legacy = SDL_atoi(env); - } else { - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; - SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata; - if ( displaydata->use_vidmode ) { - legacy = SDL_TRUE; /* the new stuff only works with XRandR. */ - } else if ( !videodata->net_wm ) { - legacy = SDL_TRUE; /* The window manager doesn't support it */ - } else { - /* !!! FIXME: look at the window manager name, and blacklist certain ones? */ - /* http://stackoverflow.com/questions/758648/find-the-name-of-the-x-window-manager */ - legacy = SDL_FALSE; /* try the new way. */ - } - } - - if (legacy) { - if (fullscreen) { - X11_BeginWindowFullscreenLegacy(_this, window, _display); - } else { - X11_EndWindowFullscreenLegacy(_this, window, _display); - } - } else { - X11_SetWindowFullscreenViaWM(_this, window, _display, fullscreen); - } + X11_SetWindowFullscreenViaWM(_this, window, _display, fullscreen); } - int X11_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) { @@ -1707,7 +1551,7 @@ X11_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size) unsigned long real_nitems; SDL_x11Prop atomProp; - X11_XGetWindowAttributes(display, X11_IsWindowLegacyFullscreen(_this, window) ? data->fswindow : data->xwindow, &attributes); + X11_XGetWindowAttributes(display, data->xwindow, &attributes); if (X11_XScreenNumberOfScreen(attributes.screen) > 0) { SDL_snprintf(icc_atom_string, sizeof("_ICC_PROFILE_") + 12, "%s%d", "_ICC_PROFILE_", X11_XScreenNumberOfScreen(attributes.screen)); } else { @@ -1748,7 +1592,6 @@ X11_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; Display *display; - SDL_bool oldstyle_fullscreen; if (data == NULL) { return; @@ -1756,13 +1599,7 @@ X11_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed) display = data->videodata->display; - /* ICCCM2.0-compliant window managers can handle fullscreen windows - If we're using XVidMode to change resolution we need to confine - the cursor so we don't pan around the virtual desktop. - */ - oldstyle_fullscreen = X11_IsWindowLegacyFullscreen(_this, window); - - if (oldstyle_fullscreen || grabbed) { + if (grabbed) { /* If the window is unmapped, XGrab calls return GrabNotViewable, so when we get a MapNotify later, we'll try to update the grab as appropriate. */ @@ -1796,11 +1633,6 @@ X11_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed) /* Raise the window if we grab the mouse */ X11_XRaiseWindow(display, data->xwindow); - - /* Now grab the keyboard on old-style fullscreen */ - if (oldstyle_fullscreen) { - X11_SetWindowKeyboardGrab(_this, window, SDL_TRUE); - } } else { X11_XUngrabPointer(display, CurrentTime); diff --git a/src/video/x11/SDL_x11window.h b/src/video/x11/SDL_x11window.h index 6f1c71c67..6f7560afe 100644 --- a/src/video/x11/SDL_x11window.h +++ b/src/video/x11/SDL_x11window.h @@ -44,7 +44,6 @@ typedef struct { SDL_Window *window; Window xwindow; - Window fswindow; /* used if we can't have the WM handle fullscreen. */ Visual *visual; Colormap colormap; #ifndef NO_SHARED_MEMORY diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 330af47c4..3738bf130 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,10 @@ cmake_minimum_required(VERSION 3.0.0) project(SDL2 C) +include(CTest) + +if(SDL_INSTALL_TESTS) + include(GNUInstallDirs) +endif() # Global settings for all of the test targets # FIXME: is this wrong? @@ -48,8 +53,8 @@ endif() add_executable(checkkeys checkkeys.c) add_executable(checkkeysthreads checkkeysthreads.c) -add_executable(loopwave loopwave.c) -add_executable(loopwavequeue loopwavequeue.c) +add_executable(loopwave loopwave.c testutils.c) +add_executable(loopwavequeue loopwavequeue.c testutils.c) add_executable(testsurround testsurround.c) add_executable(testresample testresample.c) add_executable(testaudioinfo testaudioinfo.c) @@ -57,8 +62,8 @@ add_executable(testaudioinfo testaudioinfo.c) file(GLOB TESTAUTOMATION_SOURCE_FILES testautomation*.c) add_executable(testautomation ${TESTAUTOMATION_SOURCE_FILES}) -add_executable(testmultiaudio testmultiaudio.c) -add_executable(testaudiohotplug testaudiohotplug.c) +add_executable(testmultiaudio testmultiaudio.c testutils.c) +add_executable(testaudiohotplug testaudiohotplug.c testutils.c) add_executable(testaudiocapture testaudiocapture.c) add_executable(testatomic testatomic.c) add_executable(testintersections testintersections.c) @@ -68,9 +73,14 @@ add_executable(testdraw2 testdraw2.c) add_executable(testdrawchessboard testdrawchessboard.c) add_executable(testdropfile testdropfile.c) add_executable(testerror testerror.c) + +if(LINUX) + add_executable(testevdev testevdev.c) +endif() + add_executable(testfile testfile.c) -add_executable(testgamecontroller testgamecontroller.c) -add_executable(testgeometry testgeometry.c) +add_executable(testgamecontroller testgamecontroller.c testutils.c) +add_executable(testgeometry testgeometry.c testutils.c) add_executable(testgesture testgesture.c) add_executable(testgl2 testgl2.c) add_executable(testgles testgles.c) @@ -79,52 +89,164 @@ add_executable(testhaptic testhaptic.c) add_executable(testhotplug testhotplug.c) add_executable(testrumble testrumble.c) add_executable(testthread testthread.c) -add_executable(testiconv testiconv.c) -add_executable(testime testime.c) +add_executable(testiconv testiconv.c testutils.c) +add_executable(testime testime.c testutils.c) add_executable(testjoystick testjoystick.c) add_executable(testkeys testkeys.c) add_executable(testloadso testloadso.c) +add_executable(testlocale testlocale.c) add_executable(testlock testlock.c) add_executable(testmouse testmouse.c) if(APPLE) add_executable(testnative testnative.c testnativecocoa.m - testnativex11.c) + testnativex11.c + testutils.c) elseif(WINDOWS) - add_executable(testnative testnative.c testnativew32.c) -elseif(UNIX) - add_executable(testnative testnative.c testnativex11.c) + add_executable(testnative testnative.c testnativew32.c testutils.c) +elseif(SDL_X11) + add_executable(testnative testnative.c testnativex11.c testutils.c) + target_link_libraries(testnative X11) endif() -add_executable(testoverlay2 testoverlay2.c testyuv_cvt.c) +add_executable(testoverlay2 testoverlay2.c testyuv_cvt.c testutils.c) add_executable(testplatform testplatform.c) add_executable(testpower testpower.c) add_executable(testfilesystem testfilesystem.c) -add_executable(testrendertarget testrendertarget.c) -add_executable(testscale testscale.c) +add_executable(testrendertarget testrendertarget.c testutils.c) +add_executable(testscale testscale.c testutils.c) add_executable(testsem testsem.c) +add_executable(testsensor testsensor.c) add_executable(testshader testshader.c) add_executable(testshape testshape.c) -add_executable(testsprite2 testsprite2.c) -add_executable(testspriteminimal testspriteminimal.c) -add_executable(teststreaming teststreaming.c) +add_executable(testsprite2 testsprite2.c testutils.c) +add_executable(testspriteminimal testspriteminimal.c testutils.c) +add_executable(teststreaming teststreaming.c testutils.c) add_executable(testtimer testtimer.c) +add_executable(testurl testurl.c) add_executable(testver testver.c) -add_executable(testviewport testviewport.c) +add_executable(testviewport testviewport.c testutils.c) add_executable(testwm2 testwm2.c) add_executable(testyuv testyuv.c testyuv_cvt.c) add_executable(torturethread torturethread.c) -add_executable(testrendercopyex testrendercopyex.c) +add_executable(testrendercopyex testrendercopyex.c testutils.c) add_executable(testmessage testmessage.c) add_executable(testdisplayinfo testdisplayinfo.c) add_executable(testqsort testqsort.c) add_executable(testbounds testbounds.c) add_executable(testcustomcursor testcustomcursor.c) -add_executable(controllermap controllermap.c) +add_executable(controllermap controllermap.c testutils.c) add_executable(testvulkan testvulkan.c) add_executable(testoffscreen testoffscreen.c) +SET(ALL_TESTS + checkkeys + checkkeysthreads + controllermap + loopwave + loopwavequeue + testatomic + testaudiocapture + testaudiohotplug + testaudioinfo + testautomation + testbounds + testcustomcursor + testdisplayinfo + testdraw2 + testdrawchessboard + testdropfile + testerror + testfile + testfilesystem + testgamecontroller + testgeometry + testgesture + testgl2 + testgles + testgles2 + testhaptic + testhittesting + testhotplug + testiconv + testime + testintersections + testjoystick + testkeys + testloadso + testlocale + testlock + testmessage + testmouse + testmultiaudio + testoffscreen + testoverlay2 + testplatform + testpower + testqsort + testrelative + testrendercopyex + testrendertarget + testresample + testrumble + testscale + testsem + testsensor + testshader + testshape + testsprite2 + testspriteminimal + teststreaming + testsurround + testthread + testtimer + testurl + testver + testviewport + testvulkan + testwm2 + testyuv + torturethread +) + +set(NONINTERACTIVE + testatomic + testerror + testfilesystem + testlocale + testplatform + testpower + testqsort + testthread + testtimer + testver +) + +if(WINDOWS OR APPLE OR SDL_X11) + list(APPEND ALL_TESTS testnative) +endif() + +if(LINUX) + list(APPEND ALL_TESTS testevdev) + list(APPEND NONINTERACTIVE testevdev) +endif() + +if(SDL_DUMMYAUDIO) + set(NEEDS_AUDIO + testaudioinfo + testsurround + ) +endif() + +if(SDL_DUMMYVIDEO) + set(NEEDS_DISPLAY + testkeys + testbounds + testdisplayinfo + ) +endif() + if(OPENGL_FOUND) add_dependencies(testshader OpenGL::GL) add_dependencies(testgl2 OpenGL::GL) @@ -177,12 +299,14 @@ else() testaudiohotplug testmultiaudio testime - testnative testiconv testoverlay2 teststreaming testviewport ) + if(WINDOWS OR APPLE OR SDL_X11) + list(APPEND NEEDS_RESOURCES testnative) + endif() endif() if(PSP) @@ -298,3 +422,40 @@ if(APPLE) endforeach() endif() endif() + +set(TESTS_ENVIRONMENT + SDL_AUDIODRIVER=dummy + SDL_VIDEODRIVER=dummy +) + +foreach(TESTCASE ${NONINTERACTIVE} ${NEEDS_AUDIO} ${NEEDS_DISPLAY}) + add_test( + NAME ${TESTCASE} + COMMAND ${TESTCASE} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) + set_tests_properties( + ${TESTCASE} + PROPERTIES ENVIRONMENT "${TESTS_ENVIRONMENT}" + ) + if(SDL_INSTALL_TESTS) + set(exe ${TESTCASE}) + set(installedtestsdir "${CMAKE_INSTALL_FULL_LIBEXECDIR}/installed-tests/SDL2") + configure_file(template.test.in "${exe}.test" @ONLY) + install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/${exe}.test" + DESTINATION ${CMAKE_INSTALL_DATADIR}/installed-tests/SDL2 + ) + endif() +endforeach() + +if(SDL_INSTALL_TESTS) + install( + TARGETS ${ALL_TESTS} + DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/installed-tests/SDL2 + ) + install( + FILES ${RESOURCE_FILES} + DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/installed-tests/SDL2 + ) +endif() diff --git a/test/Makefile.in b/test/Makefile.in index f724618c6..8fce76e61 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -2,6 +2,15 @@ srcdir = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +libdir = @libdir@ +libexecdir = @libexecdir@ +includedir = @includedir@ +datarootdir = @datarootdir@ +datadir = @datadir@ + CC = @CC@ EXE = @EXE@ CFLAGS = @CFLAGS@ -g @@ -79,7 +88,24 @@ TARGETS = \ @OPENGLES2_TARGETS@ += testgles2$(EXE) -all: Makefile $(TARGETS) copydatafiles +all: Makefile $(TARGETS) copydatafiles generatetestmeta + +installedtestsdir = $(libexecdir)/installed-tests/SDL2 +installedtestsmetadir = $(datadir)/installed-tests/SDL2 + +generatetestmeta: + rm -f *.test + set -e; for exe in $(noninteractive) $(needs_audio) $(needs_display); do \ + sed \ + -e 's#@installedtestsdir@#$(installedtestsdir)#g' \ + -e "s#@exe@#$$exe#g" \ + < $(srcdir)/template.test.in > $$exe.test; \ + done + +install: all + install -D -t $(DESTDIR)$(installedtestsdir) $(TARGETS) + install -m644 -D -t $(DESTDIR)$(installedtestsdir) $(DATA) + install -m644 -D -t $(DESTDIR)$(installedtestsmetadir) *.test Makefile: $(srcdir)/Makefile.in $(SHELL) config.status $@ @@ -90,10 +116,10 @@ checkkeys$(EXE): $(srcdir)/checkkeys.c checkkeysthreads$(EXE): $(srcdir)/checkkeysthreads.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) -loopwave$(EXE): $(srcdir)/loopwave.c +loopwave$(EXE): $(srcdir)/loopwave.c $(srcdir)/testutils.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) -loopwavequeue$(EXE): $(srcdir)/loopwavequeue.c +loopwavequeue$(EXE): $(srcdir)/loopwavequeue.c $(srcdir)/testutils.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) testsurround$(EXE): $(srcdir)/testsurround.c @@ -126,10 +152,10 @@ testautomation$(EXE): $(srcdir)/testautomation.c \ $(srcdir)/testautomation_hints.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) -testmultiaudio$(EXE): $(srcdir)/testmultiaudio.c +testmultiaudio$(EXE): $(srcdir)/testmultiaudio.c $(srcdir)/testutils.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) -testaudiohotplug$(EXE): $(srcdir)/testaudiohotplug.c +testaudiohotplug$(EXE): $(srcdir)/testaudiohotplug.c $(srcdir)/testutils.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) testaudiocapture$(EXE): $(srcdir)/testaudiocapture.c @@ -165,10 +191,10 @@ testevdev$(EXE): $(srcdir)/testevdev.c testfile$(EXE): $(srcdir)/testfile.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) -testgamecontroller$(EXE): $(srcdir)/testgamecontroller.c +testgamecontroller$(EXE): $(srcdir)/testgamecontroller.c $(srcdir)/testutils.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) -testgeometry$(EXE): $(srcdir)/testgeometry.c +testgeometry$(EXE): $(srcdir)/testgeometry.c $(srcdir)/testutils.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) testgesture$(EXE): $(srcdir)/testgesture.c @@ -183,7 +209,7 @@ testgles$(EXE): $(srcdir)/testgles.c testgles2$(EXE): $(srcdir)/testgles2.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@ -testgles2_sdf$(EXE): $(srcdir)/testgles2_sdf.c +testgles2_sdf$(EXE): $(srcdir)/testgles2_sdf.c $(srcdir)/testutils.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@ testhaptic$(EXE): $(srcdir)/testhaptic.c @@ -198,10 +224,10 @@ testrumble$(EXE): $(srcdir)/testrumble.c testthread$(EXE): $(srcdir)/testthread.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) -testiconv$(EXE): $(srcdir)/testiconv.c +testiconv$(EXE): $(srcdir)/testiconv.c $(srcdir)/testutils.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) -testime$(EXE): $(srcdir)/testime.c +testime$(EXE): $(srcdir)/testime.c $(srcdir)/testutils.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) @SDL_TTF_LIB@ testjoystick$(EXE): $(srcdir)/testjoystick.c @@ -219,18 +245,21 @@ testlock$(EXE): $(srcdir)/testlock.c ifeq (@ISMACOSX@,true) testnative$(EXE): $(srcdir)/testnative.c \ $(srcdir)/testnativecocoa.m \ + $(srcdir)/testutils.c \ $(srcdir)/testnativex11.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) -framework Cocoa @XLIB@ endif ifeq (@ISWINDOWS@,true) testnative$(EXE): $(srcdir)/testnative.c \ + $(srcdir)/testutils.c \ $(srcdir)/testnativew32.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) endif ifeq (@ISUNIX@,true) testnative$(EXE): $(srcdir)/testnative.c \ + $(srcdir)/testutils.c \ $(srcdir)/testnativex11.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) @XLIB@ endif @@ -252,7 +281,7 @@ endif endif endif -testoverlay2$(EXE): $(srcdir)/testoverlay2.c $(srcdir)/testyuv_cvt.c +testoverlay2$(EXE): $(srcdir)/testoverlay2.c $(srcdir)/testyuv_cvt.c $(srcdir)/testutils.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) testplatform$(EXE): $(srcdir)/testplatform.c @@ -264,10 +293,10 @@ testpower$(EXE): $(srcdir)/testpower.c testfilesystem$(EXE): $(srcdir)/testfilesystem.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) -testrendertarget$(EXE): $(srcdir)/testrendertarget.c +testrendertarget$(EXE): $(srcdir)/testrendertarget.c $(srcdir)/testutils.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) -testscale$(EXE): $(srcdir)/testscale.c +testscale$(EXE): $(srcdir)/testscale.c $(srcdir)/testutils.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) testsem$(EXE): $(srcdir)/testsem.c @@ -282,13 +311,13 @@ testshader$(EXE): $(srcdir)/testshader.c testshape$(EXE): $(srcdir)/testshape.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) -testsprite2$(EXE): $(srcdir)/testsprite2.c +testsprite2$(EXE): $(srcdir)/testsprite2.c $(srcdir)/testutils.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) -testspriteminimal$(EXE): $(srcdir)/testspriteminimal.c +testspriteminimal$(EXE): $(srcdir)/testspriteminimal.c $(srcdir)/testutils.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@ -teststreaming$(EXE): $(srcdir)/teststreaming.c +teststreaming$(EXE): $(srcdir)/teststreaming.c $(srcdir)/testutils.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@ testtimer$(EXE): $(srcdir)/testtimer.c @@ -300,7 +329,7 @@ testurl$(EXE): $(srcdir)/testurl.c testver$(EXE): $(srcdir)/testver.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) -testviewport$(EXE): $(srcdir)/testviewport.c +testviewport$(EXE): $(srcdir)/testviewport.c $(srcdir)/testutils.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) testwm2$(EXE): $(srcdir)/testwm2.c @@ -312,7 +341,7 @@ testyuv$(EXE): $(srcdir)/testyuv.c $(srcdir)/testyuv_cvt.c torturethread$(EXE): $(srcdir)/torturethread.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) -testrendercopyex$(EXE): $(srcdir)/testrendercopyex.c +testrendercopyex$(EXE): $(srcdir)/testrendercopyex.c $(srcdir)/testutils.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@ testmessage$(EXE): $(srcdir)/testmessage.c @@ -330,7 +359,7 @@ testbounds$(EXE): $(srcdir)/testbounds.c testcustomcursor$(EXE): $(srcdir)/testcustomcursor.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) -controllermap$(EXE): $(srcdir)/controllermap.c +controllermap$(EXE): $(srcdir)/controllermap.c $(srcdir)/testutils.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) testvulkan$(EXE): $(srcdir)/testvulkan.c @@ -344,13 +373,56 @@ testmouse$(EXE): $(srcdir)/testmouse.c clean: - rm -f $(TARGETS) + rm -f $(TARGETS) *.test distclean: clean rm -f Makefile rm -f config.status config.cache config.log rm -rf $(srcdir)/autom4te* +noninteractive = \ + testatomic$(EXE) \ + testerror$(EXE) \ + testevdev$(EXE) \ + testfilesystem$(EXE) \ + testkeys$(EXE) \ + testlocale$(EXE) \ + testplatform$(EXE) \ + testpower$(EXE) \ + testqsort$(EXE) \ + testthread$(EXE) \ + testtimer$(EXE) \ + testver$(EXE) \ + $(NULL) + +needs_audio = \ + testaudioinfo$(EXE) \ + testsurround$(EXE) \ + $(NULL) + +needs_display = \ + testbounds$(EXE) \ + testdisplayinfo$(EXE) \ + $(NULL) + +TESTS = $(noninteractive) $(needs_audio) $(needs_display) + +check: + @set -e; \ + status=0; \ + export SDL_AUDIODRIVER=dummy; \ + export SDL_VIDEODRIVER=dummy; \ + for exe in $(TESTS); do \ + echo "$$exe..."; \ + if ./"$$exe"; then \ + echo "$$exe: OK"; \ + else \ + echo "$$exe: FAILED: $$?"; \ + status=1; \ + fi; \ + done; \ + exit "$$status" + DATA = \ axis.bmp \ button.bmp \ diff --git a/test/Makefile.os2 b/test/Makefile.os2 index e238af4be..75aaeedfd 100644 --- a/test/Makefile.os2 +++ b/test/Makefile.os2 @@ -1,77 +1,13 @@ # Open Watcom makefile to build SDL2 tests for OS/2 # wmake -f Makefile.os2 -INCPATH = -I"$(%WATCOM)/h/os2" -I"$(%WATCOM)/h" -I"../include" +SYSTEM = os2v2 -CFLAGS = $(INCPATH) -bt=os2 -d0 -q -bm -5s -fp5 -fpi87 -sg -oteanbmier -ei +INCPATH = -I"$(%WATCOM)/h/os2" -I"$(%WATCOM)/h" + +CFLAGS = -bt=os2 -d0 -q -bm -5s -fp5 -fpi87 -sg -oteanbmier -ei CFLAGS+= -wx -wcd=303 -LIBPATH = .. -LIBS = SDL2.lib SDL2test.lib +TNSRCS = testnative.c testnativeos2.c -#CFLAGS+= -DHAVE_SDL_TTF -#TTFLIBS = SDL2ttf.lib - -TARGETS = testatomic.exe testdisplayinfo.exe testbounds.exe testdraw2.exe & - testdrawchessboard.exe testdropfile.exe testerror.exe testfile.exe & - testfilesystem.exe testgamecontroller.exe testgeometry.exe testgesture.exe & - testhittesting.exe testhotplug.exe testiconv.exe testime.exe testlocale.exe & - testintersections.exe testjoystick.exe testkeys.exe testloadso.exe & - testlock.exe testmessage.exe testoverlay2.exe testplatform.exe & - testpower.exe testsensor.exe testrelative.exe testrendercopyex.exe & - testrendertarget.exe testrumble.exe testscale.exe testsem.exe & - testshader.exe testshape.exe testsprite2.exe testspriteminimal.exe & - teststreaming.exe testthread.exe testtimer.exe testver.exe & - testviewport.exe testwm2.exe torturethread.exe checkkeys.exe & - checkkeysthreads.exe testmouse.exe & - controllermap.exe testhaptic.exe testqsort.exe testresample.exe & - testaudioinfo.exe testaudiocapture.exe loopwave.exe loopwavequeue.exe & - testsurround.exe testyuv.exe testgl2.exe testvulkan.exe testnative.exe & - testautomation.exe - -# testautomation sources -TASRCS = testautomation.c testautomation_audio.c testautomation_clipboard.c & - testautomation_events.c testautomation_hints.c & - testautomation_keyboard.c testautomation_main.c & - testautomation_mouse.c testautomation_pixels.c & - testautomation_platform.c testautomation_rect.c & - testautomation_render.c testautomation_rwops.c & - testautomation_sdltest.c testautomation_stdlib.c & - testautomation_surface.c testautomation_syswm.c & - testautomation_timer.c testautomation_video.c - -OBJS = $(TARGETS:.exe=.obj) -COBJS = $(CSRCS:.c=.obj) -TAOBJS = $(TASRCS:.c=.obj) - -all: $(TARGETS) - -.c: ../src/test - -.obj.exe: - wlink SYS os2v2 libpath $(LIBPATH) lib {$(LIBS)} op q op el file {$<} name $@ - -.c.obj: - wcc386 $(CFLAGS) -fo=$^@ $< - -# specials -testautomation.exe: $(TAOBJS) - wlink SYS os2v2 libpath $(LIBPATH) lib {$(LIBS)} op q op el file {$<} name $@ - -testnative.exe: testnative.obj testnativeos2.obj - wlink SYS os2v2 libpath $(LIBPATH) lib {$(LIBS)} op q op el file {$<} name $@ - -testoverlay2.exe: testoverlay2.obj testyuv_cvt.obj - wlink SYS os2v2 libpath $(LIBPATH) lib {$(LIBS)} op q op el file {$<} name $@ - -testyuv.exe: testyuv.obj testyuv_cvt.obj - wlink SYS os2v2 libpath $(LIBPATH) lib {$(LIBS)} op q op el file {$<} name $@ - -testime.exe: testime.obj - wlink SYS os2v2 libpath $(LIBPATH) lib {$(LIBS) $(TTFLIBS)} op q op el file {$<} name $@ - -clean: .SYMBOLIC - @if exist *.obj rm *.obj - @if exist *.err rm *.err -distclean: .SYMBOLIC clean - @if exist *.exe rm *.exe +!include watcom.mif diff --git a/test/Makefile.w32 b/test/Makefile.w32 new file mode 100644 index 000000000..5e3e6bcaa --- /dev/null +++ b/test/Makefile.w32 @@ -0,0 +1,17 @@ +# Open Watcom makefile to build SDL2 tests for Win32 +# wmake -f Makefile.w32 + +SYSTEM = nt + +INCPATH = -I"$(%WATCOM)/h/nt" -I"$(%WATCOM)/h" -I"../src/video/khronos" + +CFLAGS = -bt=nt -d0 -q -bm -5s -fp5 -fpi87 -sg -oteanbmier -ei +CFLAGS+= -wx -wcd=303 +CFLAGS+= -DSDL_MAIN_HANDLED + +CFLAGS+= -DHAVE_OPENGL +GLLIBS = opengl32.lib + +TNSRCS = testnative.obj testnativew32.obj + +!include watcom.mif diff --git a/test/checkkeys.c b/test/checkkeys.c index caec4b955..74bd7953c 100644 --- a/test/checkkeys.c +++ b/test/checkkeys.c @@ -165,7 +165,11 @@ loop() PrintKey(&event.key.keysym, (event.key.state == SDL_PRESSED) ? SDL_TRUE : SDL_FALSE, (event.key.repeat) ? SDL_TRUE : SDL_FALSE); break; case SDL_TEXTEDITING: - PrintText("EDIT", event.text.text); + PrintText("EDIT", event.edit.text); + break; + case SDL_TEXTEDITING_EXT: + PrintText("EDIT_EXT", event.editExt.text); + SDL_free(event.editExt.text); break; case SDL_TEXTINPUT: PrintText("INPUT", event.text.text); @@ -207,6 +211,9 @@ main(int argc, char *argv[]) /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); + /* Enable extended text editing events */ + SDL_SetHint(SDL_HINT_IME_SUPPORT_EXTENDED_TEXT, "1"); + /* Initialize SDL */ if (SDL_Init(SDL_INIT_VIDEO) < 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); diff --git a/test/controllermap.c b/test/controllermap.c index 308ddf51a..429125a19 100644 --- a/test/controllermap.c +++ b/test/controllermap.c @@ -18,6 +18,7 @@ #include #include "SDL.h" +#include "testutils.h" #ifndef SDL_JOYSTICK_DISABLED @@ -169,39 +170,6 @@ static SDL_Renderer *screen; static SDL_bool done = SDL_FALSE; static SDL_bool bind_touchpad = SDL_FALSE; -SDL_Texture * -LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent) -{ - SDL_Surface *temp; - SDL_Texture *texture; - - /* Load the sprite image */ - temp = SDL_LoadBMP(file); - if (temp == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError()); - return NULL; - } - - /* Set transparent pixel as the pixel at (0,0) */ - if (transparent) { - if (temp->format->palette) { - SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels); - } - } - - /* Create textures from the image */ - texture = SDL_CreateTextureFromSurface(renderer, temp); - if (!texture) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError()); - SDL_FreeSurface(temp); - return NULL; - } - SDL_FreeSurface(temp); - - /* We're ready to roll. :) */ - return texture; -} - static int StandardizeAxisValue(int nValue) { @@ -392,10 +360,10 @@ WatchJoystick(SDL_Joystick * joystick) Uint32 alpha_ticks = 0; SDL_JoystickID nJoystickID; - background_front = LoadTexture(screen, "controllermap.bmp", SDL_FALSE); - background_back = LoadTexture(screen, "controllermap_back.bmp", SDL_FALSE); - button = LoadTexture(screen, "button.bmp", SDL_TRUE); - axis = LoadTexture(screen, "axis.bmp", SDL_TRUE); + background_front = LoadTexture(screen, "controllermap.bmp", SDL_FALSE, NULL, NULL); + background_back = LoadTexture(screen, "controllermap_back.bmp", SDL_FALSE, NULL, NULL); + button = LoadTexture(screen, "button.bmp", SDL_TRUE, NULL, NULL); + axis = LoadTexture(screen, "axis.bmp", SDL_TRUE, NULL, NULL); SDL_RaiseWindow(window); /* scale for platforms that don't give you the window size you asked for. */ diff --git a/test/gcc-fat.sh b/test/gcc-fat.sh deleted file mode 100755 index 44d37ffde..000000000 --- a/test/gcc-fat.sh +++ /dev/null @@ -1,110 +0,0 @@ -#!/bin/sh -# -# Build Universal binaries on Mac OS X, thanks Ryan! -# -# Usage: ./configure CC="sh gcc-fat.sh" && make && rm -rf ppc x86 - -# PowerPC compiler flags (10.2 runtime compatibility) -GCC_COMPILE_PPC="gcc-3.3 -arch ppc \ --DMAC_OS_X_VERSION_MIN_REQUIRED=1020 \ --nostdinc \ --F/Developer/SDKs/MacOSX10.2.8.sdk/System/Library/Frameworks \ --I/Developer/SDKs/MacOSX10.2.8.sdk/usr/include/gcc/darwin/3.3 \ --isystem /Developer/SDKs/MacOSX10.2.8.sdk/usr/include" - -GCC_LINK_PPC="\ --L/Developer/SDKs/MacOSX10.2.8.sdk/usr/lib/gcc/darwin/3.3 \ --F/Developer/SDKs/MacOSX10.2.8.sdk/System/Library/Frameworks \ --Wl,-syslibroot,/Developer/SDKs/MacOSX10.2.8.sdk" - -# Intel compiler flags (10.4 runtime compatibility) -GCC_COMPILE_X86="gcc-4.0 -arch i386 -mmacosx-version-min=10.4 \ --DMAC_OS_X_VERSION_MIN_REQUIRED=1040 \ --nostdinc \ --F/Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks \ --I/Developer/SDKs/MacOSX10.4u.sdk/usr/lib/gcc/i686-apple-darwin8/4.0.1/include \ --isystem /Developer/SDKs/MacOSX10.4u.sdk/usr/include" - -GCC_LINK_X86="\ --L/Developer/SDKs/MacOSX10.4u.sdk/usr/lib/gcc/i686-apple-darwin8/4.0.0 \ --Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk" - -# Output both PowerPC and Intel object files -args="$*" -compile=yes -link=yes -while test x$1 != x; do - case $1 in - --version) exec gcc $1;; - -v) exec gcc $1;; - -V) exec gcc $1;; - -print-prog-name=*) exec gcc $1;; - -print-search-dirs) exec gcc $1;; - -E) GCC_COMPILE_PPC="$GCC_COMPILE_PPC -E" - GCC_COMPILE_X86="$GCC_COMPILE_X86 -E" - compile=no; link=no;; - -c) link=no;; - -o) output=$2;; - *.c|*.cc|*.cpp|*.S) source=$1;; - esac - shift -done -if test x$link = xyes; then - GCC_COMPILE_PPC="$GCC_COMPILE_PPC $GCC_LINK_PPC" - GCC_COMPILE_X86="$GCC_COMPILE_X86 $GCC_LINK_X86" -fi -if test x"$output" = x; then - if test x$link = xyes; then - output=a.out - elif test x$compile = xyes; then - output=`echo $source | sed -e 's|.*/||' -e 's|\(.*\)\.[^\.]*|\1|'`.o - fi -fi - -if test x"$output" != x; then - dir=ppc/`dirname $output` - if test -d $dir; then - : - else - mkdir -p $dir - fi -fi -set -- $args -while test x$1 != x; do - if test -f "ppc/$1" && test "$1" != "$output"; then - ppc_args="$ppc_args ppc/$1" - else - ppc_args="$ppc_args $1" - fi - shift -done -$GCC_COMPILE_PPC $ppc_args || exit $? -if test x"$output" != x; then - cp $output ppc/$output -fi - -if test x"$output" != x; then - dir=x86/`dirname $output` - if test -d $dir; then - : - else - mkdir -p $dir - fi -fi -set -- $args -while test x$1 != x; do - if test -f "x86/$1" && test "$1" != "$output"; then - x86_args="$x86_args x86/$1" - else - x86_args="$x86_args $1" - fi - shift -done -$GCC_COMPILE_X86 $x86_args || exit $? -if test x"$output" != x; then - cp $output x86/$output -fi - -if test x"$output" != x; then - lipo -create -o $output ppc/$output x86/$output -fi diff --git a/test/loopwave.c b/test/loopwave.c index 14ac4dbaf..354ac2cb7 100644 --- a/test/loopwave.c +++ b/test/loopwave.c @@ -25,6 +25,7 @@ #endif #include "SDL.h" +#include "testutils.h" static struct { @@ -114,7 +115,7 @@ int main(int argc, char *argv[]) { int i; - char filename[4096]; + char *filename = NULL; /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); @@ -125,11 +126,13 @@ main(int argc, char *argv[]) return (1); } - if (argc > 1) { - SDL_strlcpy(filename, argv[1], sizeof(filename)); - } else { - SDL_strlcpy(filename, "sample.wav", sizeof(filename)); + filename = GetResourceFilename(argc > 1 ? argv[1] : NULL, "sample.wav"); + + if (filename == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s\n", SDL_GetError()); + quit(1); } + /* Load the wave file into memory */ if (SDL_LoadWAV(filename, &wave.spec, &wave.sound, &wave.soundlen) == NULL) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError()); @@ -172,6 +175,7 @@ main(int argc, char *argv[]) /* Clean up on signal */ close_audio(); SDL_FreeWAV(wave.sound); + SDL_free(filename); SDL_Quit(); return (0); } diff --git a/test/loopwavequeue.c b/test/loopwavequeue.c index a5d0ea3cc..1996d784a 100644 --- a/test/loopwavequeue.c +++ b/test/loopwavequeue.c @@ -25,6 +25,8 @@ #include #endif +#include "testutils.h" + static struct { SDL_AudioSpec spec; @@ -74,7 +76,7 @@ loop() int main(int argc, char *argv[]) { - char filename[4096]; + char *filename = NULL; /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); @@ -85,11 +87,13 @@ main(int argc, char *argv[]) return (1); } - if (argc > 1) { - SDL_strlcpy(filename, argv[1], sizeof(filename)); - } else { - SDL_strlcpy(filename, "sample.wav", sizeof(filename)); + filename = GetResourceFilename(argc > 1 ? argv[1] : NULL, "sample.wav"); + + if (filename == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s\n", SDL_GetError()); + quit(1); } + /* Load the wave file into memory */ if (SDL_LoadWAV(filename, &wave.spec, &wave.sound, &wave.soundlen) == NULL) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError()); @@ -142,6 +146,7 @@ main(int argc, char *argv[]) /* Clean up on signal */ SDL_CloseAudio(); SDL_FreeWAV(wave.sound); + SDL_free(filename); SDL_Quit(); return 0; } diff --git a/test/template.test.in b/test/template.test.in new file mode 100644 index 000000000..e1ac063fd --- /dev/null +++ b/test/template.test.in @@ -0,0 +1,3 @@ +[Test] +Type=session +Exec=@installedtestsdir@/@exe@ diff --git a/test/testatomic.c b/test/testatomic.c index 16678db5d..7dbad45a4 100644 --- a/test/testatomic.c +++ b/test/testatomic.c @@ -709,6 +709,12 @@ main(int argc, char *argv[]) SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); RunBasicTest(); + + if (SDL_getenv("SDL_TESTS_QUICK") != NULL) { + SDL_Log("Not running slower tests"); + return 0; + } + RunEpicTest(); /* This test is really slow, so don't run it by default */ #if 0 diff --git a/test/testaudiohotplug.c b/test/testaudiohotplug.c index 536cc4c3b..dc84a782f 100644 --- a/test/testaudiohotplug.c +++ b/test/testaudiohotplug.c @@ -26,6 +26,7 @@ #endif #include "SDL.h" +#include "testutils.h" static SDL_AudioSpec spec; static Uint8 *sound = NULL; /* Pointer to wave data */ @@ -137,7 +138,7 @@ int main(int argc, char *argv[]) { int i; - char filename[4096]; + char *filename = NULL; /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); @@ -151,11 +152,13 @@ main(int argc, char *argv[]) /* Some targets (Mac CoreAudio) need an event queue for audio hotplug, so make and immediately hide a window. */ SDL_MinimizeWindow(SDL_CreateWindow("testaudiohotplug", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0)); - if (argc > 1) { - SDL_strlcpy(filename, argv[1], sizeof(filename)); - } else { - SDL_strlcpy(filename, "sample.wav", sizeof(filename)); + filename = GetResourceFilename(argc > 1 ? argv[1] : NULL, "sample.wav"); + + if (filename == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s\n", SDL_GetError()); + quit(1); } + /* Load the wave file into memory */ if (SDL_LoadWAV(filename, &spec, &sound, &soundlen) == NULL) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError()); @@ -196,6 +199,7 @@ main(int argc, char *argv[]) /* Quit audio first, then free WAV. This prevents access violations in the audio threads. */ SDL_QuitSubSystem(SDL_INIT_AUDIO); SDL_FreeWAV(sound); + SDL_free(filename); SDL_Quit(); return (0); } diff --git a/test/testautomation_hints.c b/test/testautomation_hints.c index 0d1b7b6f5..91b8c02ab 100644 --- a/test/testautomation_hints.c +++ b/test/testautomation_hints.c @@ -8,7 +8,6 @@ #include "SDL_test.h" -const int _numHintsEnum = 25; const char* _HintsEnum[] = { SDL_HINT_ACCELEROMETER_AS_JOYSTICK, @@ -32,9 +31,7 @@ const char* _HintsEnum[] = SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT, SDL_HINT_VIDEO_WIN_D3DCOMPILER, - SDL_HINT_VIDEO_X11_XINERAMA, SDL_HINT_VIDEO_X11_XRANDR, - SDL_HINT_VIDEO_X11_XVIDMODE, SDL_HINT_XINPUT_ENABLED, }; const char* _HintsVerbose[] = @@ -60,12 +57,13 @@ const char* _HintsVerbose[] = "SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS", "SDL_VIDEO_WINDOW_SHARE_PIXEL_FORMAT", "SDL_VIDEO_WIN_D3DCOMPILER", - "SDL_VIDEO_X11_XINERAMA", "SDL_VIDEO_X11_XRANDR", - "SDL_VIDEO_X11_XVIDMODE", "SDL_XINPUT_ENABLED" }; +SDL_COMPILE_TIME_ASSERT(HintsEnum, SDL_arraysize(_HintsEnum) == SDL_arraysize(_HintsVerbose)); + +const int _numHintsEnum = SDL_arraysize(_HintsEnum); /* Test case functions */ diff --git a/test/testautomation_platform.c b/test/testautomation_platform.c index 4e28ba166..0a31ad8cf 100644 --- a/test/testautomation_platform.c +++ b/test/testautomation_platform.c @@ -54,12 +54,18 @@ int platform_testTypes(void *arg) int platform_testEndianessAndSwap(void *arg) { int real_byteorder; + int real_floatwordorder = 0; Uint16 value = 0x1234; Uint16 value16 = 0xCDAB; Uint16 swapped16 = 0xABCD; Uint32 value32 = 0xEFBEADDE; Uint32 swapped32 = 0xDEADBEEF; + union { + double d; + Uint32 ui32[2]; + } value_double; + Uint64 value64, swapped64; value64 = 0xEFBEADDE; value64 <<= 32; @@ -67,6 +73,7 @@ int platform_testEndianessAndSwap(void *arg) swapped64 = 0x1234ABCD; swapped64 <<= 32; swapped64 |= 0xDEADBEEF; + value_double.d = 3.141593; if ((*((char *) &value) >> 4) == 0x1) { real_byteorder = SDL_BIG_ENDIAN; @@ -80,6 +87,18 @@ int platform_testEndianessAndSwap(void *arg) (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? "little" : "big", (real_byteorder == SDL_LIL_ENDIAN) ? "little" : "big" ); + if (value_double.ui32[0] == 0x82c2bd7f && value_double.ui32[1] == 0x400921fb) { + real_floatwordorder = SDL_LIL_ENDIAN; + } else if (value_double.ui32[0] == 0x400921fb && value_double.ui32[1] == 0x82c2bd7f) { + real_floatwordorder = SDL_BIG_ENDIAN; + } + + /* Test endianness. */ + SDLTest_AssertCheck( real_floatwordorder == SDL_FLOATWORDORDER, + "Machine detected as having %s endian float word order, appears to be %s endian.", + (SDL_FLOATWORDORDER == SDL_LIL_ENDIAN) ? "little" : "big", + (real_floatwordorder == SDL_LIL_ENDIAN) ? "little" : (real_floatwordorder == SDL_BIG_ENDIAN) ? "big" : "unknown" ); + /* Test 16 swap. */ SDLTest_AssertCheck( SDL_Swap16(value16) == swapped16, "SDL_Swap16(): 16 bit swapped: 0x%X => 0x%X", diff --git a/test/testautomation_stdlib.c b/test/testautomation_stdlib.c index bfc8ad373..4c978fa9b 100644 --- a/test/testautomation_stdlib.c +++ b/test/testautomation_stdlib.c @@ -322,6 +322,168 @@ stdlib_sscanf(void *arg) return TEST_COMPLETED; } +#if defined(_WIN64) +# define SIZE_FORMAT "I64u" +#elif defined(__WIN32__) +# define SIZE_FORMAT "I32u" +#else +# define SIZE_FORMAT "zu" +#endif + +typedef struct +{ + size_t a; + size_t b; + size_t result; + int status; +} overflow_test; + +static const overflow_test multiplications[] = +{ + { 1, 1, 1, 0 }, + { 0, 0, 0, 0 }, + { SDL_SIZE_MAX, 0, 0, 0 }, + { SDL_SIZE_MAX, 1, SDL_SIZE_MAX, 0 }, + { SDL_SIZE_MAX / 2, 2, SDL_SIZE_MAX - (SDL_SIZE_MAX % 2), 0 }, + { SDL_SIZE_MAX / 23, 23, SDL_SIZE_MAX - (SDL_SIZE_MAX % 23), 0 }, + + { (SDL_SIZE_MAX / 2) + 1, 2, 0, -1 }, + { (SDL_SIZE_MAX / 23) + 42, 23, 0, -1 }, + { SDL_SIZE_MAX, SDL_SIZE_MAX, 0, -1 }, +}; + +static const overflow_test additions[] = +{ + { 1, 1, 2, 0 }, + { 0, 0, 0, 0 }, + { SDL_SIZE_MAX, 0, SDL_SIZE_MAX, 0 }, + { SDL_SIZE_MAX - 1, 1, SDL_SIZE_MAX, 0 }, + { SDL_SIZE_MAX - 42, 23, SDL_SIZE_MAX - (42 - 23), 0 }, + + { SDL_SIZE_MAX, 1, 0, -1 }, + { SDL_SIZE_MAX, 23, 0, -1 }, + { SDL_SIZE_MAX, SDL_SIZE_MAX, 0, -1 }, +}; + +static int +stdlib_overflow(void *arg) +{ + size_t i; + size_t useBuiltin; + + for (useBuiltin = 0; useBuiltin < 2; useBuiltin++) { + if (useBuiltin) { + SDLTest_Log("Using gcc/clang builtins if possible"); + } else { + SDLTest_Log("Not using gcc/clang builtins"); + } + + for (i = 0; i < SDL_arraysize(multiplications); i++) { + const overflow_test *t = &multiplications[i]; + int status; + size_t result = ~t->result; + + if (useBuiltin) { + status = SDL_size_mul_overflow(t->a, t->b, &result); + } else { + /* This disables the macro that tries to use a gcc/clang + * builtin, so we test the fallback implementation instead. */ + status = (SDL_size_mul_overflow)(t->a, t->b, &result); + } + + if (t->status == 0) { + SDLTest_AssertCheck(status == 0, + "(%" SIZE_FORMAT " * %" SIZE_FORMAT ") should succeed", + t->a, t->b); + SDLTest_AssertCheck(result == t->result, + "(%" SIZE_FORMAT " * %" SIZE_FORMAT "): expected %" SIZE_FORMAT ", got %" SIZE_FORMAT, + t->a, t->b, t->result, result); + } else { + SDLTest_AssertCheck(status == -1, + "(%" SIZE_FORMAT " * %" SIZE_FORMAT ") should fail", + t->a, t->b); + } + + if (t->a == t->b) { + continue; + } + + result = ~t->result; + + if (useBuiltin) { + status = SDL_size_mul_overflow(t->b, t->a, &result); + } else { + status = (SDL_size_mul_overflow)(t->b, t->a, &result); + } + + if (t->status == 0) { + SDLTest_AssertCheck(status == 0, + "(%" SIZE_FORMAT " * %" SIZE_FORMAT ") should succeed", + t->b, t->a); + SDLTest_AssertCheck(result == t->result, + "(%" SIZE_FORMAT " * %" SIZE_FORMAT "): expected %" SIZE_FORMAT ", got %" SIZE_FORMAT, + t->b, t->a, t->result, result); + } else { + SDLTest_AssertCheck(status == -1, + "(%" SIZE_FORMAT " * %" SIZE_FORMAT ") should fail", + t->b, t->a); + } + } + + for (i = 0; i < SDL_arraysize(additions); i++) { + const overflow_test *t = &additions[i]; + int status; + size_t result = ~t->result; + + if (useBuiltin) { + status = SDL_size_add_overflow(t->a, t->b, &result); + } else { + status = (SDL_size_add_overflow)(t->a, t->b, &result); + } + + if (t->status == 0) { + SDLTest_AssertCheck(status == 0, + "(%" SIZE_FORMAT " + %" SIZE_FORMAT ") should succeed", + t->a, t->b); + SDLTest_AssertCheck(result == t->result, + "(%" SIZE_FORMAT " + %" SIZE_FORMAT "): expected %" SIZE_FORMAT ", got %" SIZE_FORMAT, + t->a, t->b, t->result, result); + } else { + SDLTest_AssertCheck(status == -1, + "(%" SIZE_FORMAT " + %" SIZE_FORMAT ") should fail", + t->a, t->b); + } + + if (t->a == t->b) { + continue; + } + + result = ~t->result; + + if (useBuiltin) { + status = SDL_size_add_overflow(t->b, t->a, &result); + } else { + status = (SDL_size_add_overflow)(t->b, t->a, &result); + } + + if (t->status == 0) { + SDLTest_AssertCheck(status == 0, + "(%" SIZE_FORMAT " + %" SIZE_FORMAT ") should succeed", + t->b, t->a); + SDLTest_AssertCheck(result == t->result, + "(%" SIZE_FORMAT " + %" SIZE_FORMAT "): expected %" SIZE_FORMAT ", got %" SIZE_FORMAT, + t->b, t->a, t->result, result); + } else { + SDLTest_AssertCheck(status == -1, + "(%" SIZE_FORMAT " + %" SIZE_FORMAT ") should fail", + t->b, t->a); + } + } + } + + return TEST_COMPLETED; +} + /* ================= Test References ================== */ /* Standard C routine test cases */ @@ -337,9 +499,17 @@ static const SDLTest_TestCaseReference stdlibTest3 = static const SDLTest_TestCaseReference stdlibTest4 = { (SDLTest_TestCaseFp)stdlib_sscanf, "stdlib_sscanf", "Call to SDL_sscanf", TEST_ENABLED }; +static const SDLTest_TestCaseReference stdlibTestOverflow = + { stdlib_overflow, "stdlib_overflow", "Overflow detection", TEST_ENABLED }; + /* Sequence of Standard C routine test cases */ static const SDLTest_TestCaseReference *stdlibTests[] = { - &stdlibTest1, &stdlibTest2, &stdlibTest3, &stdlibTest4, NULL + &stdlibTest1, + &stdlibTest2, + &stdlibTest3, + &stdlibTest4, + &stdlibTestOverflow, + NULL }; /* Standard C routine test suite (global) */ diff --git a/test/testcustomcursor.c b/test/testcustomcursor.c index 2feee81a2..d29c1c56f 100644 --- a/test/testcustomcursor.c +++ b/test/testcustomcursor.c @@ -160,7 +160,28 @@ loop() if (current_cursor == SDL_arraysize(cursors)) { current_cursor = 0; } + SDL_SetCursor(cursors[current_cursor]); + + if (current_cursor == 0) { + SDL_Log("Custom cursor"); + } else { + switch ((SDL_SystemCursor) (current_cursor-1)) { + case SDL_SYSTEM_CURSOR_ARROW: SDL_Log("Arrow"); break; + case SDL_SYSTEM_CURSOR_IBEAM: SDL_Log("I-beam"); break; + case SDL_SYSTEM_CURSOR_WAIT: SDL_Log("Wait"); break; + case SDL_SYSTEM_CURSOR_CROSSHAIR: SDL_Log("Crosshair"); break; + case SDL_SYSTEM_CURSOR_WAITARROW: SDL_Log("Small wait cursor (or Wait if not available)"); break; + case SDL_SYSTEM_CURSOR_SIZENWSE: SDL_Log("Double arrow pointing northwest and southeast"); break; + case SDL_SYSTEM_CURSOR_SIZENESW: SDL_Log("Double arrow pointing northeast and southwest"); break; + case SDL_SYSTEM_CURSOR_SIZEWE: SDL_Log("Double arrow pointing west and east"); break; + case SDL_SYSTEM_CURSOR_SIZENS: SDL_Log("Double arrow pointing north and south"); break; + case SDL_SYSTEM_CURSOR_SIZEALL: SDL_Log("Four pointed arrow pointing north, south, east, and west"); break; + case SDL_SYSTEM_CURSOR_NO: SDL_Log("Slashed circle or crossbones"); break; + case SDL_SYSTEM_CURSOR_HAND: SDL_Log("Hand"); break; + default: SDL_Log("UNKNOWN CURSOR TYPE, FIX THIS PROGRAM."); break; + } + } } else { show_cursor = !show_cursor; SDL_ShowCursor(show_cursor); diff --git a/test/testerror.c b/test/testerror.c index e847c2824..c118abdee 100644 --- a/test/testerror.c +++ b/test/testerror.c @@ -58,6 +58,12 @@ main(int argc, char *argv[]) /* Set the error value for the main thread */ SDL_SetError("No worries"); + if (SDL_getenv("SDL_TESTS_QUICK") != NULL) { + SDL_Log("Not running slower tests"); + SDL_Quit(); + return 0; + } + alive = 1; thread = SDL_CreateThread(ThreadFunc, NULL, "#1"); if (thread == NULL) { diff --git a/test/testevdev.c b/test/testevdev.c index 76a12ef7e..938a9a504 100644 --- a/test/testevdev.c +++ b/test/testevdev.c @@ -1019,7 +1019,7 @@ static int run_test(void) { printf("SDL compiled without evdev capability check.\n"); - return 0; + return 1; } #endif diff --git a/test/testgamecontroller.c b/test/testgamecontroller.c index 17fb60bd3..011e5cd6d 100644 --- a/test/testgamecontroller.c +++ b/test/testgamecontroller.c @@ -17,6 +17,7 @@ #include #include "SDL.h" +#include "testutils.h" #ifdef __EMSCRIPTEN__ #include @@ -27,6 +28,10 @@ #define SCREEN_WIDTH 512 #define SCREEN_HEIGHT 320 +#define BUTTON_SIZE 50 +#define AXIS_SIZE 50 + + /* This is indexed by SDL_GameControllerButton. */ static const struct { int x; int y; } button_positions[] = { {387, 167}, /* SDL_CONTROLLER_BUTTON_A */ @@ -49,7 +54,9 @@ static const struct { int x; int y; } button_positions[] = { {330, 135}, /* SDL_CONTROLLER_BUTTON_PADDLE2 */ {132, 175}, /* SDL_CONTROLLER_BUTTON_PADDLE3 */ {330, 175}, /* SDL_CONTROLLER_BUTTON_PADDLE4 */ + {0, 0}, /* SDL_CONTROLLER_BUTTON_TOUCHPAD */ }; +SDL_COMPILE_TIME_ASSERT(button_positions, SDL_arraysize(button_positions) == SDL_CONTROLLER_BUTTON_MAX); /* This is indexed by SDL_GameControllerAxis. */ static const struct { int x; int y; double angle; } axis_positions[] = { @@ -60,6 +67,7 @@ static const struct { int x; int y; double angle; } axis_positions[] = { {91, -20, 0.0}, /* TRIGGERLEFT */ {375, -20, 0.0}, /* TRIGGERRIGHT */ }; +SDL_COMPILE_TIME_ASSERT(axis_positions, SDL_arraysize(axis_positions) == SDL_CONTROLLER_AXIS_MAX); static SDL_Window *window = NULL; static SDL_Renderer *screen = NULL; @@ -71,6 +79,11 @@ static SDL_Texture *background_front, *background_back, *button, *axis; static SDL_GameController *gamecontroller; static SDL_GameController **gamecontrollers; static int num_controllers = 0; +static SDL_Joystick *virtual_joystick = NULL; +static SDL_GameControllerAxis virtual_axis_active = SDL_CONTROLLER_AXIS_INVALID; +static int virtual_axis_start_x; +static int virtual_axis_start_y; +static SDL_GameControllerButton virtual_button_active = SDL_CONTROLLER_BUTTON_INVALID; static void UpdateWindowTitle() { @@ -151,7 +164,8 @@ static void AddController(int device_index, SDL_bool verbose) if (verbose) { const char *name = SDL_GameControllerName(gamecontroller); - SDL_Log("Opened game controller %s\n", name); + const char *path = SDL_GameControllerPath(gamecontroller); + SDL_Log("Opened game controller %s%s%s\n", name, path ? ", " : "", path ? path : ""); } if (SDL_GameControllerHasSensor(gamecontroller, SDL_SENSOR_ACCEL)) { @@ -216,34 +230,6 @@ static void DelController(SDL_JoystickID controller) UpdateWindowTitle(); } -static SDL_Texture * -LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent) -{ - SDL_Surface *temp = NULL; - SDL_Texture *texture = NULL; - - temp = SDL_LoadBMP(file); - if (temp == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError()); - } else { - /* Set transparent pixel as the pixel at (0,0) */ - if (transparent) { - if (temp->format->BytesPerPixel == 1) { - SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *)temp->pixels); - } - } - - texture = SDL_CreateTextureFromSurface(renderer, temp); - if (!texture) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError()); - } - } - if (temp) { - SDL_FreeSurface(temp); - } - return texture; -} - static Uint16 ConvertAxisToRumble(Sint16 axisval) { /* Only start rumbling if the axis is past the halfway point */ @@ -306,12 +292,223 @@ static void CyclePS5TriggerEffect() SDL_GameControllerSendEffect(gamecontroller, &state, sizeof(state)); } +static SDL_bool ShowingFront() +{ + SDL_bool showing_front = SDL_TRUE; + int i; + + if (gamecontroller) { + /* Show the back of the controller if the paddles are being held */ + for (i = SDL_CONTROLLER_BUTTON_PADDLE1; i <= SDL_CONTROLLER_BUTTON_PADDLE4; ++i) { + if (SDL_GameControllerGetButton(gamecontroller, (SDL_GameControllerButton)i) == SDL_PRESSED) { + showing_front = SDL_FALSE; + break; + } + } + } + if ((SDL_GetModState() & KMOD_SHIFT) != 0) { + showing_front = SDL_FALSE; + } + return showing_front; +} + +static void SDLCALL VirtualControllerSetPlayerIndex(void *userdata, int player_index) +{ + SDL_Log("Virtual Controller: player index set to %d\n", player_index); +} + +static int SDLCALL VirtualControllerRumble(void *userdata, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + SDL_Log("Virtual Controller: rumble set to %d/%d\n", low_frequency_rumble, high_frequency_rumble); + return 0; +} + +static int SDLCALL VirtualControllerRumbleTriggers(void *userdata, Uint16 left_rumble, Uint16 right_rumble) +{ + SDL_Log("Virtual Controller: trigger rumble set to %d/%d\n", left_rumble, right_rumble); + return 0; +} + +static int SDLCALL VirtualControllerSetLED(void *userdata, Uint8 red, Uint8 green, Uint8 blue) +{ + SDL_Log("Virtual Controller: LED set to RGB %d,%d,%d\n", red, green, blue); + return 0; +} + +static void OpenVirtualController() +{ + SDL_VirtualJoystickDesc desc; + int virtual_index; + + SDL_zero(desc); + desc.version = SDL_VIRTUAL_JOYSTICK_DESC_VERSION; + desc.type = SDL_JOYSTICK_TYPE_GAMECONTROLLER; + desc.naxes = SDL_CONTROLLER_AXIS_MAX; + desc.nbuttons = SDL_CONTROLLER_BUTTON_MAX; + desc.SetPlayerIndex = VirtualControllerSetPlayerIndex; + desc.Rumble = VirtualControllerRumble; + desc.RumbleTriggers = VirtualControllerRumbleTriggers; + desc.SetLED = VirtualControllerSetLED; + + virtual_index = SDL_JoystickAttachVirtualEx(&desc); + if (virtual_index < 0) { + SDL_Log("Couldn't open virtual device: %s\n", SDL_GetError()); + } else { + virtual_joystick = SDL_JoystickOpen(virtual_index); + if (!virtual_joystick) { + SDL_Log("Couldn't open virtual device: %s\n", SDL_GetError()); + } + } +} + +static void CloseVirtualController() +{ + int i; + + for (i = SDL_NumJoysticks(); i--; ) { + if (SDL_JoystickIsVirtual(i)) { + SDL_JoystickDetachVirtual(i); + } + } + + if (virtual_joystick) { + SDL_JoystickClose(virtual_joystick); + virtual_joystick = NULL; + } +} + +static SDL_GameControllerButton FindButtonAtPosition(int x, int y) +{ + SDL_Point point; + int i; + SDL_bool showing_front = ShowingFront(); + + point.x = x; + point.y = y; + for (i = 0; i < SDL_CONTROLLER_BUTTON_TOUCHPAD; ++i) { + SDL_bool on_front = (i < SDL_CONTROLLER_BUTTON_PADDLE1 || i > SDL_CONTROLLER_BUTTON_PADDLE4); + if (on_front == showing_front) { + SDL_Rect rect; + rect.x = button_positions[i].x; + rect.y = button_positions[i].y; + rect.w = BUTTON_SIZE; + rect.h = BUTTON_SIZE; + if (SDL_PointInRect(&point, &rect)) { + return (SDL_GameControllerButton)i; + } + } + } + return SDL_CONTROLLER_BUTTON_INVALID; +} + +static SDL_GameControllerAxis FindAxisAtPosition(int x, int y) +{ + SDL_Point point; + int i; + SDL_bool showing_front = ShowingFront(); + + point.x = x; + point.y = y; + for (i = 0; i < SDL_CONTROLLER_AXIS_MAX; ++i) { + if (showing_front) { + SDL_Rect rect; + rect.x = axis_positions[i].x; + rect.y = axis_positions[i].y; + rect.w = AXIS_SIZE; + rect.h = AXIS_SIZE; + if (SDL_PointInRect(&point, &rect)) { + return (SDL_GameControllerAxis)i; + } + } + } + return SDL_CONTROLLER_AXIS_INVALID; +} + +static void VirtualControllerMouseMotion(int x, int y) +{ + if (virtual_button_active != SDL_CONTROLLER_BUTTON_INVALID) { + if (virtual_axis_active != SDL_CONTROLLER_AXIS_INVALID) { + const int MOVING_DISTANCE = 2; + if (SDL_abs(x - virtual_axis_start_x) >= MOVING_DISTANCE || + SDL_abs(y - virtual_axis_start_y) >= MOVING_DISTANCE) { + SDL_JoystickSetVirtualButton(virtual_joystick, virtual_button_active, SDL_RELEASED); + virtual_button_active = SDL_CONTROLLER_BUTTON_INVALID; + } + } + } + + if (virtual_axis_active != SDL_CONTROLLER_AXIS_INVALID) { + if (virtual_axis_active == SDL_CONTROLLER_AXIS_TRIGGERLEFT || + virtual_axis_active == SDL_CONTROLLER_AXIS_TRIGGERRIGHT) { + int range = (SDL_JOYSTICK_AXIS_MAX - SDL_JOYSTICK_AXIS_MIN); + float distance = SDL_clamp(((float)y - virtual_axis_start_y) / AXIS_SIZE, 0.0f, 1.0f); + Sint16 value = (Sint16)(SDL_JOYSTICK_AXIS_MIN + (distance * range)); + SDL_JoystickSetVirtualAxis(virtual_joystick, virtual_axis_active, value); + } else { + float distanceX = SDL_clamp(((float)x - virtual_axis_start_x) / AXIS_SIZE, -1.0f, 1.0f); + float distanceY = SDL_clamp(((float)y - virtual_axis_start_y) / AXIS_SIZE, -1.0f, 1.0f); + Sint16 valueX, valueY; + + if (distanceX >= 0) { + valueX = (Sint16)(distanceX * SDL_JOYSTICK_AXIS_MAX); + } else { + valueX = (Sint16)(distanceX * -SDL_JOYSTICK_AXIS_MIN); + } + if (distanceY >= 0) { + valueY = (Sint16)(distanceY * SDL_JOYSTICK_AXIS_MAX); + } else { + valueY = (Sint16)(distanceY * -SDL_JOYSTICK_AXIS_MIN); + } + SDL_JoystickSetVirtualAxis(virtual_joystick, virtual_axis_active, valueX); + SDL_JoystickSetVirtualAxis(virtual_joystick, virtual_axis_active+1, valueY); + } + } +} + +static void VirtualControllerMouseDown(int x, int y) +{ + SDL_GameControllerButton button; + SDL_GameControllerAxis axis; + + button = FindButtonAtPosition(x, y); + if (button != SDL_CONTROLLER_BUTTON_INVALID) { + virtual_button_active = button; + SDL_JoystickSetVirtualButton(virtual_joystick, virtual_button_active, SDL_PRESSED); + } + + axis = FindAxisAtPosition(x, y); + if (axis != SDL_CONTROLLER_AXIS_INVALID) { + virtual_axis_active = axis; + virtual_axis_start_x = x; + virtual_axis_start_y = y; + } +} + +static void VirtualControllerMouseUp(int x, int y) +{ + if (virtual_button_active != SDL_CONTROLLER_BUTTON_INVALID) { + SDL_JoystickSetVirtualButton(virtual_joystick, virtual_button_active, SDL_RELEASED); + virtual_button_active = SDL_CONTROLLER_BUTTON_INVALID; + } + + if (virtual_axis_active != SDL_CONTROLLER_AXIS_INVALID) { + if (virtual_axis_active == SDL_CONTROLLER_AXIS_TRIGGERLEFT || + virtual_axis_active == SDL_CONTROLLER_AXIS_TRIGGERRIGHT) { + SDL_JoystickSetVirtualAxis(virtual_joystick, virtual_axis_active, SDL_JOYSTICK_AXIS_MIN); + } else { + SDL_JoystickSetVirtualAxis(virtual_joystick, virtual_axis_active, 0); + SDL_JoystickSetVirtualAxis(virtual_joystick, virtual_axis_active+1, 0); + } + virtual_axis_active = SDL_CONTROLLER_AXIS_INVALID; + } +} + void loop(void *arg) { SDL_Event event; int i; - SDL_bool showing_front = SDL_TRUE; + SDL_bool showing_front; /* Update to get the current event state */ SDL_PumpEvents(); @@ -382,6 +579,24 @@ loop(void *arg) } break; + case SDL_MOUSEBUTTONDOWN: + if (virtual_joystick) { + VirtualControllerMouseDown(event.button.x, event.button.y); + } + break; + + case SDL_MOUSEBUTTONUP: + if (virtual_joystick) { + VirtualControllerMouseUp(event.button.x, event.button.y); + } + break; + + case SDL_MOUSEMOTION: + if (virtual_joystick) { + VirtualControllerMouseMotion(event.motion.x, event.motion.y); + } + break; + case SDL_KEYDOWN: if (event.key.keysym.sym >= SDLK_0 && event.key.keysym.sym <= SDLK_9) { if (gamecontroller) { @@ -391,6 +606,14 @@ loop(void *arg) } break; } + if (event.key.keysym.sym == SDLK_a) { + OpenVirtualController(); + break; + } + if (event.key.keysym.sym == SDLK_d) { + CloseVirtualController(); + break; + } if (event.key.keysym.sym != SDLK_ESCAPE) { break; } @@ -403,15 +626,7 @@ loop(void *arg) } } - if (gamecontroller) { - /* Show the back of the controller if the paddles are being held */ - for (i = SDL_CONTROLLER_BUTTON_PADDLE1; i <= SDL_CONTROLLER_BUTTON_PADDLE4; ++i) { - if (SDL_GameControllerGetButton(gamecontroller, (SDL_GameControllerButton)i) == SDL_PRESSED) { - showing_front = SDL_FALSE; - break; - } - } - } + showing_front = ShowingFront(); /* blank screen, set up for drawing this frame. */ SDL_SetRenderDrawColor(screen, 0xFF, 0xFF, 0xFF, SDL_ALPHA_OPAQUE); @@ -427,8 +642,8 @@ loop(void *arg) SDL_Rect dst; dst.x = button_positions[i].x; dst.y = button_positions[i].y; - dst.w = 50; - dst.h = 50; + dst.w = BUTTON_SIZE; + dst.h = BUTTON_SIZE; SDL_RenderCopyEx(screen, button, NULL, &dst, 0, NULL, SDL_FLIP_NONE); } } @@ -443,16 +658,16 @@ loop(void *arg) SDL_Rect dst; dst.x = axis_positions[i].x; dst.y = axis_positions[i].y; - dst.w = 50; - dst.h = 50; + dst.w = AXIS_SIZE; + dst.h = AXIS_SIZE; SDL_RenderCopyEx(screen, axis, NULL, &dst, angle, NULL, SDL_FLIP_NONE); } else if (value > deadzone) { const double angle = axis_positions[i].angle + 180.0; SDL_Rect dst; dst.x = axis_positions[i].x; dst.y = axis_positions[i].y; - dst.w = 50; - dst.h = 50; + dst.w = AXIS_SIZE; + dst.h = AXIS_SIZE; SDL_RenderCopyEx(screen, axis, NULL, &dst, angle, NULL, SDL_FLIP_NONE); } } @@ -507,7 +722,7 @@ loop(void *arg) } } } - + SDL_Delay(16); SDL_RenderPresent(screen); #ifdef __EMSCRIPTEN__ @@ -560,6 +775,7 @@ main(int argc, char *argv[]) /* Print information about the controller */ for (i = 0; i < SDL_NumJoysticks(); ++i) { const char *name; + const char *path; const char *description; SDL_JoystickGetGUIDString(SDL_JoystickGetDeviceGUID(i), @@ -568,6 +784,7 @@ main(int argc, char *argv[]) if (SDL_IsGameController(i)) { controller_count++; name = SDL_GameControllerNameForIndex(i); + path = SDL_GameControllerPathForIndex(i); switch (SDL_GameControllerTypeForIndex(i)) { case SDL_CONTROLLER_TYPE_AMAZON_LUNA: description = "Amazon Luna Controller"; @@ -603,10 +820,11 @@ main(int argc, char *argv[]) AddController(i, SDL_FALSE); } else { name = SDL_JoystickNameForIndex(i); + path = SDL_JoystickPathForIndex(i); description = "Joystick"; } - SDL_Log("%s %d: %s (guid %s, VID 0x%.4x, PID 0x%.4x, player index = %d)\n", - description, i, name ? name : "Unknown", guid, + SDL_Log("%s %d: %s%s%s (guid %s, VID 0x%.4x, PID 0x%.4x, player index = %d)\n", + description, i, name ? name : "Unknown", path ? ", " : "", path ? path : "", guid, SDL_JoystickGetDeviceVendor(i), SDL_JoystickGetDeviceProduct(i), SDL_JoystickGetDevicePlayerIndex(i)); } SDL_Log("There are %d game controller(s) attached (%d joystick(s))\n", controller_count, SDL_NumJoysticks()); @@ -634,10 +852,10 @@ main(int argc, char *argv[]) /* scale for platforms that don't give you the window size you asked for. */ SDL_RenderSetLogicalSize(screen, SCREEN_WIDTH, SCREEN_HEIGHT); - background_front = LoadTexture(screen, "controllermap.bmp", SDL_FALSE); - background_back = LoadTexture(screen, "controllermap_back.bmp", SDL_FALSE); - button = LoadTexture(screen, "button.bmp", SDL_TRUE); - axis = LoadTexture(screen, "axis.bmp", SDL_TRUE); + background_front = LoadTexture(screen, "controllermap.bmp", SDL_FALSE, NULL, NULL); + background_back = LoadTexture(screen, "controllermap_back.bmp", SDL_FALSE, NULL, NULL); + button = LoadTexture(screen, "button.bmp", SDL_TRUE, NULL, NULL); + axis = LoadTexture(screen, "axis.bmp", SDL_TRUE, NULL, NULL); if (!background_front || !background_back || !button || !axis) { SDL_DestroyRenderer(screen); @@ -650,8 +868,14 @@ main(int argc, char *argv[]) /* !!! FIXME: */ /*SDL_RenderSetLogicalSize(screen, background->w, background->h);*/ - if (argv[1] && *argv[1] != '-') { - controller_index = SDL_atoi(argv[1]); + for (i = 1; i < argc; ++i) { + if (SDL_strcmp(argv[i], "--virtual") == 0) { + OpenVirtualController(); + } + if (argv[i] && *argv[i] != '-') { + controller_index = SDL_atoi(argv[i]); + break; + } } if (controller_index < num_controllers) { gamecontroller = gamecontrollers[controller_index]; @@ -675,6 +899,7 @@ main(int argc, char *argv[]) CyclePS5TriggerEffect(); } + CloseVirtualController(); SDL_DestroyRenderer(screen); SDL_DestroyWindow(window); SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER); diff --git a/test/testgeometry.c b/test/testgeometry.c index 3a87e3d2e..f0f07eed6 100644 --- a/test/testgeometry.c +++ b/test/testgeometry.c @@ -21,6 +21,7 @@ #endif #include "SDL_test_common.h" +#include "testutils.h" static SDLTest_CommonState *state; static SDL_bool use_texture = SDL_FALSE; @@ -44,54 +45,19 @@ int LoadSprite(const char *file) { int i; - SDL_Surface *temp; - /* Load the sprite image */ - temp = SDL_LoadBMP(file); - if (temp == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError()); - return (-1); - } - sprite_w = temp->w; - sprite_h = temp->h; - - /* Set transparent pixel as the pixel at (0,0) */ - if (temp->format->palette) { - SDL_SetColorKey(temp, 1, *(Uint8 *) temp->pixels); - } else { - switch (temp->format->BitsPerPixel) { - case 15: - SDL_SetColorKey(temp, 1, (*(Uint16 *) temp->pixels) & 0x00007FFF); - break; - case 16: - SDL_SetColorKey(temp, 1, *(Uint16 *) temp->pixels); - break; - case 24: - SDL_SetColorKey(temp, 1, (*(Uint32 *) temp->pixels) & 0x00FFFFFF); - break; - case 32: - SDL_SetColorKey(temp, 1, *(Uint32 *) temp->pixels); - break; - } - } - - /* Create textures from the image */ for (i = 0; i < state->num_windows; ++i) { - SDL_Renderer *renderer = state->renderers[i]; - sprites[i] = SDL_CreateTextureFromSurface(renderer, temp); + /* This does the SDL_LoadBMP step repeatedly, but that's OK for test code. */ + sprites[i] = LoadTexture(state->renderers[i], file, SDL_TRUE, &sprite_w, &sprite_h); if (!sprites[i]) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError()); - SDL_FreeSurface(temp); return (-1); } if (SDL_SetTextureBlendMode(sprites[i], blendMode) < 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set blend mode: %s\n", SDL_GetError()); - SDL_FreeSurface(temp); SDL_DestroyTexture(sprites[i]); return (-1); } } - SDL_FreeSurface(temp); /* We're ready to roll. :) */ return (0); diff --git a/test/testgles2_sdf.c b/test/testgles2_sdf.c index a7f8016ea..064b6bc2c 100644 --- a/test/testgles2_sdf.c +++ b/test/testgles2_sdf.c @@ -458,6 +458,7 @@ main(int argc, char *argv[]) Uint32 then, now; int status; shader_data *data; + char *path = NULL; /* Initialize parameters */ fsaa = 0; @@ -561,14 +562,25 @@ main(int argc, char *argv[]) /* Load SDF BMP image */ #if 1 - tmp = SDL_LoadBMP(f); - if (tmp == NULL) { - SDL_Log("missing image file: %s", f); + path = GetNearbyFilename(f); + + if (path == NULL) + path = SDL_strdup(f); + + if (path == NULL) { + SDL_Log("out of memory\n"); exit(-1); - } else { - SDL_Log("Load image file: %s", f); } + tmp = SDL_LoadBMP(path); + if (tmp == NULL) { + SDL_Log("missing image file: %s", path); + exit(-1); + } else { + SDL_Log("Load image file: %s", path); + } + + SDL_free(path); #else /* Generate SDF image using SDL_ttf */ diff --git a/test/testiconv.c b/test/testiconv.c index bf9ad3b92..31d05e195 100644 --- a/test/testiconv.c +++ b/test/testiconv.c @@ -13,6 +13,7 @@ #include #include "SDL.h" +#include "testutils.h" static size_t widelen(char *data) @@ -43,7 +44,7 @@ main(int argc, char *argv[]) "UCS-4", }; - const char * fname; + char * fname; char buffer[BUFSIZ]; char *ucs4; char *test[2]; @@ -54,12 +55,13 @@ main(int argc, char *argv[]) /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - fname = (argc < 2) ? "utf8.txt" : argv[1]; + fname = GetResourceFilename(argc > 1 ? argv[1] : NULL, "utf8.txt"); file = fopen(fname, "rb"); if (!file) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to open %s\n", fname); return (1); } + SDL_free(fname); while (fgets(buffer, sizeof(buffer), file)) { /* Convert to UCS-4 */ diff --git a/test/testime.c b/test/testime.c index 5541d484f..155834229 100644 --- a/test/testime.c +++ b/test/testime.c @@ -23,6 +23,7 @@ #endif #include "SDL_test_common.h" +#include "testutils.h" #define DEFAULT_PTSIZE 30 #ifdef HAVE_SDL_TTF @@ -108,6 +109,7 @@ static int unifont_init(const char *fontname) SDL_RWops *hexFile; const size_t unifontGlyphSize = UNIFONT_NUM_GLYPHS * sizeof(struct UnifontGlyph); const size_t unifontTextureSize = UNIFONT_NUM_TEXTURES * state->num_windows * sizeof(void *); + char *filename; /* Allocate memory for the glyph data so the file can be closed after initialization. */ unifontGlyph = (struct UnifontGlyph *)SDL_malloc(unifontGlyphSize); @@ -127,7 +129,13 @@ static int unifont_init(const char *fontname) } SDL_memset(unifontTexture, 0, unifontTextureSize); - hexFile = SDL_RWFromFile(fontname, "rb"); + filename = GetResourceFilename(NULL, fontname); + if (filename == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory\n"); + return -1; + } + hexFile = SDL_RWFromFile(filename, "rb"); + SDL_free(filename); if (hexFile == NULL) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Failed to open font file: %s\n", fontname); diff --git a/test/testmultiaudio.c b/test/testmultiaudio.c index 51a7ff03c..1154b83af 100644 --- a/test/testmultiaudio.c +++ b/test/testmultiaudio.c @@ -17,6 +17,8 @@ #include #endif +#include "testutils.h" + static SDL_AudioSpec spec; static Uint8 *sound = NULL; /* Pointer to wave data */ static Uint32 soundlen = 0; /* Length of wave data */ @@ -180,7 +182,7 @@ main(int argc, char **argv) if (devcount < 1) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Don't see any specific audio devices!\n"); } else { - const char *file = (argc < 2) ? "sample.wav" : argv[1]; + char *file = GetResourceFilename(argc > 1 ? argv[1] : NULL, "sample.wav"); /* Load the wave file into memory */ if (SDL_LoadWAV(file, &spec, &sound, &soundlen) == NULL) { @@ -190,6 +192,8 @@ main(int argc, char **argv) test_multi_audio(devcount); SDL_FreeWAV(sound); } + + SDL_free(file); } SDL_Quit(); diff --git a/test/testnative.c b/test/testnative.c index 48f6f0ea5..34ee661f9 100644 --- a/test/testnative.c +++ b/test/testnative.c @@ -16,6 +16,7 @@ #include /* for time() */ #include "testnative.h" +#include "testutils.h" #define WINDOW_W 640 #define WINDOW_H 480 @@ -52,37 +53,6 @@ quit(int rc) exit(rc); } -SDL_Texture * -LoadSprite(SDL_Renderer *renderer, const char *file) -{ - SDL_Surface *temp; - SDL_Texture *sprite; - - /* Load the sprite image */ - temp = SDL_LoadBMP(file); - if (temp == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError()); - return 0; - } - - /* Set transparent pixel as the pixel at (0,0) */ - if (temp->format->palette) { - SDL_SetColorKey(temp, 1, *(Uint8 *) temp->pixels); - } - - /* Create textures from the image */ - sprite = SDL_CreateTextureFromSurface(renderer, temp); - if (!sprite) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError()); - SDL_FreeSurface(temp); - return 0; - } - SDL_FreeSurface(temp); - - /* We're ready to roll. :) */ - return sprite; -} - void MoveSprites(SDL_Renderer * renderer, SDL_Texture * sprite) { @@ -180,7 +150,7 @@ main(int argc, char *argv[]) SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); SDL_RenderClear(renderer); - sprite = LoadSprite(renderer, "icon.bmp"); + sprite = LoadTexture(renderer, "icon.bmp", SDL_TRUE, NULL, NULL); if (!sprite) { quit(6); } diff --git a/test/testoverlay2.c b/test/testoverlay2.c index 8bb59a9fa..ab0fd82db 100644 --- a/test/testoverlay2.c +++ b/test/testoverlay2.c @@ -25,6 +25,7 @@ #include "SDL.h" #include "testyuv_cvt.h" +#include "testutils.h" #define MOOSEPIC_W 64 #define MOOSEPIC_H 88 @@ -243,6 +244,7 @@ main(int argc, char **argv) int fps = 12; int nodelay = 0; int scale = 5; + char *filename = NULL; /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); @@ -315,7 +317,13 @@ main(int argc, char **argv) } /* load the trojan moose images */ - handle = SDL_RWFromFile("moose.dat", "rb"); + filename = GetResourceFilename(NULL, "moose.dat"); + if (filename == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory\n"); + return -1; + } + handle = SDL_RWFromFile(filename, "rb"); + SDL_free(filename); if (handle == NULL) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Can't find the file moose.dat !\n"); SDL_free(RawMooseData); diff --git a/test/testplatform.c b/test/testplatform.c index 5aa649c12..f5b524d57 100644 --- a/test/testplatform.c +++ b/test/testplatform.c @@ -86,18 +86,25 @@ TestEndian(SDL_bool verbose) int error = 0; Uint16 value = 0x1234; int real_byteorder; + int real_floatwordorder = 0; Uint16 value16 = 0xCDAB; Uint16 swapped16 = 0xABCD; Uint32 value32 = 0xEFBEADDE; Uint32 swapped32 = 0xDEADBEEF; Uint64 value64, swapped64; + union { + double d; + Uint32 ui32[2]; + } value_double; + value64 = 0xEFBEADDE; value64 <<= 32; value64 |= 0xCDAB3412; swapped64 = 0x1234ABCD; swapped64 <<= 32; swapped64 |= 0xDEADBEEF; + value_double.d = 3.141593; if (verbose) { SDL_Log("Detected a %s endian machine.\n", @@ -115,6 +122,22 @@ TestEndian(SDL_bool verbose) } ++error; } + if (verbose) { + SDL_Log("Detected a %s endian float word order machine.\n", + (SDL_FLOATWORDORDER == SDL_LIL_ENDIAN) ? "little" : "big"); + } + if (value_double.ui32[0] == 0x82c2bd7f && value_double.ui32[1] == 0x400921fb) { + real_floatwordorder = SDL_LIL_ENDIAN; + } else if (value_double.ui32[0] == 0x400921fb && value_double.ui32[1] == 0x82c2bd7f) { + real_floatwordorder = SDL_BIG_ENDIAN; + } + if (real_floatwordorder != SDL_FLOATWORDORDER) { + if (verbose) { + SDL_Log("Actually a %s endian float word order machine!\n", + (real_floatwordorder == SDL_LIL_ENDIAN) ? "little" : (real_floatwordorder == SDL_BIG_ENDIAN) ? "big" : "unknown" ); + } + ++error; + } if (verbose) { SDL_Log("Value 16 = 0x%X, swapped = 0x%X\n", value16, SDL_Swap16(value16)); diff --git a/test/testqsort.c b/test/testqsort.c index d28daebd4..29ea05627 100644 --- a/test/testqsort.c +++ b/test/testqsort.c @@ -12,7 +12,7 @@ #include "SDL_test.h" -static int +static int SDLCALL num_compare(const void *_a, const void *_b) { const int a = *((const int *) _a); diff --git a/test/testrendercopyex.c b/test/testrendercopyex.c index 47d3ae96f..b954499e3 100644 --- a/test/testrendercopyex.c +++ b/test/testrendercopyex.c @@ -20,7 +20,7 @@ #endif #include "SDL_test_common.h" - +#include "testutils.h" static SDLTest_CommonState *state; @@ -44,56 +44,6 @@ quit(int rc) exit(rc); } -SDL_Texture * -LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent) -{ - SDL_Surface *temp; - SDL_Texture *texture; - - /* Load the sprite image */ - temp = SDL_LoadBMP(file); - if (temp == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError()); - return NULL; - } - - /* Set transparent pixel as the pixel at (0,0) */ - if (transparent) { - if (temp->format->palette) { - SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels); - } else { - switch (temp->format->BitsPerPixel) { - case 15: - SDL_SetColorKey(temp, SDL_TRUE, - (*(Uint16 *) temp->pixels) & 0x00007FFF); - break; - case 16: - SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels); - break; - case 24: - SDL_SetColorKey(temp, SDL_TRUE, - (*(Uint32 *) temp->pixels) & 0x00FFFFFF); - break; - case 32: - SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels); - break; - } - } - } - - /* Create textures from the image */ - texture = SDL_CreateTextureFromSurface(renderer, temp); - if (!texture) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError()); - SDL_FreeSurface(temp); - return NULL; - } - SDL_FreeSurface(temp); - - /* We're ready to roll. :) */ - return texture; -} - void Draw(DrawState *s) { @@ -186,8 +136,8 @@ main(int argc, char *argv[]) drawstate->window = state->windows[i]; drawstate->renderer = state->renderers[i]; - drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", SDL_TRUE); - drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", SDL_FALSE); + drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", SDL_TRUE, NULL, NULL); + drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", SDL_FALSE, NULL, NULL); if (!drawstate->sprite || !drawstate->background) { quit(2); } diff --git a/test/testrendertarget.c b/test/testrendertarget.c index 3fb611270..98ceb1607 100644 --- a/test/testrendertarget.c +++ b/test/testrendertarget.c @@ -20,7 +20,7 @@ #endif #include "SDL_test_common.h" - +#include "testutils.h" static SDLTest_CommonState *state; @@ -45,56 +45,6 @@ quit(int rc) exit(rc); } -SDL_Texture * -LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent) -{ - SDL_Surface *temp; - SDL_Texture *texture; - - /* Load the sprite image */ - temp = SDL_LoadBMP(file); - if (temp == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError()); - return NULL; - } - - /* Set transparent pixel as the pixel at (0,0) */ - if (transparent) { - if (temp->format->palette) { - SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels); - } else { - switch (temp->format->BitsPerPixel) { - case 15: - SDL_SetColorKey(temp, SDL_TRUE, - (*(Uint16 *) temp->pixels) & 0x00007FFF); - break; - case 16: - SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels); - break; - case 24: - SDL_SetColorKey(temp, SDL_TRUE, - (*(Uint32 *) temp->pixels) & 0x00FFFFFF); - break; - case 32: - SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels); - break; - } - } - } - - /* Create textures from the image */ - texture = SDL_CreateTextureFromSurface(renderer, temp); - if (!texture) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError()); - SDL_FreeSurface(temp); - return NULL; - } - SDL_FreeSurface(temp); - - /* We're ready to roll. :) */ - return texture; -} - SDL_bool DrawComposite(DrawState *s) { @@ -292,11 +242,11 @@ main(int argc, char *argv[]) drawstate->window = state->windows[i]; drawstate->renderer = state->renderers[i]; if (test_composite) { - drawstate->sprite = LoadTexture(drawstate->renderer, "icon-alpha.bmp", SDL_TRUE); + drawstate->sprite = LoadTexture(drawstate->renderer, "icon-alpha.bmp", SDL_TRUE, NULL, NULL); } else { - drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", SDL_TRUE); + drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", SDL_TRUE, NULL, NULL); } - drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", SDL_FALSE); + drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", SDL_FALSE, NULL, NULL); if (!drawstate->sprite || !drawstate->background) { quit(2); } diff --git a/test/testscale.c b/test/testscale.c index 1235c811d..0f1d21bfe 100644 --- a/test/testscale.c +++ b/test/testscale.c @@ -20,6 +20,7 @@ #endif #include "SDL_test_common.h" +#include "testutils.h" #define WINDOW_WIDTH 640 #define WINDOW_HEIGHT 480 @@ -46,56 +47,6 @@ quit(int rc) exit(rc); } -SDL_Texture * -LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent) -{ - SDL_Surface *temp; - SDL_Texture *texture; - - /* Load the sprite image */ - temp = SDL_LoadBMP(file); - if (temp == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError()); - return NULL; - } - - /* Set transparent pixel as the pixel at (0,0) */ - if (transparent) { - if (temp->format->palette) { - SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels); - } else { - switch (temp->format->BitsPerPixel) { - case 15: - SDL_SetColorKey(temp, SDL_TRUE, - (*(Uint16 *) temp->pixels) & 0x00007FFF); - break; - case 16: - SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels); - break; - case 24: - SDL_SetColorKey(temp, SDL_TRUE, - (*(Uint32 *) temp->pixels) & 0x00FFFFFF); - break; - case 32: - SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels); - break; - } - } - } - - /* Create textures from the image */ - texture = SDL_CreateTextureFromSurface(renderer, temp); - if (!texture) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError()); - SDL_FreeSurface(temp); - return NULL; - } - SDL_FreeSurface(temp); - - /* We're ready to roll. :) */ - return texture; -} - void Draw(DrawState *s) { @@ -176,8 +127,8 @@ main(int argc, char *argv[]) drawstate->window = state->windows[i]; drawstate->renderer = state->renderers[i]; - drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", SDL_TRUE); - drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", SDL_FALSE); + drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", SDL_TRUE, NULL, NULL); + drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", SDL_FALSE, NULL, NULL); if (!drawstate->sprite || !drawstate->background) { quit(2); } diff --git a/test/testsprite2.c b/test/testsprite2.c index 88419ffcf..fa709e349 100644 --- a/test/testsprite2.c +++ b/test/testsprite2.c @@ -21,6 +21,7 @@ #include "SDL_test.h" #include "SDL_test_common.h" +#include "testutils.h" #define NUM_SPRITES 100 #define MAX_SPEED 1 @@ -62,54 +63,19 @@ int LoadSprite(const char *file) { int i; - SDL_Surface *temp; - /* Load the sprite image */ - temp = SDL_LoadBMP(file); - if (temp == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError()); - return (-1); - } - sprite_w = temp->w; - sprite_h = temp->h; - - /* Set transparent pixel as the pixel at (0,0) */ - if (temp->format->palette) { - SDL_SetColorKey(temp, 1, *(Uint8 *) temp->pixels); - } else { - switch (temp->format->BitsPerPixel) { - case 15: - SDL_SetColorKey(temp, 1, (*(Uint16 *) temp->pixels) & 0x00007FFF); - break; - case 16: - SDL_SetColorKey(temp, 1, *(Uint16 *) temp->pixels); - break; - case 24: - SDL_SetColorKey(temp, 1, (*(Uint32 *) temp->pixels) & 0x00FFFFFF); - break; - case 32: - SDL_SetColorKey(temp, 1, *(Uint32 *) temp->pixels); - break; - } - } - - /* Create textures from the image */ for (i = 0; i < state->num_windows; ++i) { - SDL_Renderer *renderer = state->renderers[i]; - sprites[i] = SDL_CreateTextureFromSurface(renderer, temp); + /* This does the SDL_LoadBMP step repeatedly, but that's OK for test code. */ + sprites[i] = LoadTexture(state->renderers[i], file, SDL_TRUE, &sprite_w, &sprite_h); if (!sprites[i]) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError()); - SDL_FreeSurface(temp); return (-1); } if (SDL_SetTextureBlendMode(sprites[i], blendMode) < 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set blend mode: %s\n", SDL_GetError()); - SDL_FreeSurface(temp); SDL_DestroyTexture(sprites[i]); return (-1); } } - SDL_FreeSurface(temp); /* We're ready to roll. :) */ return (0); diff --git a/test/testspriteminimal.c b/test/testspriteminimal.c index b9762cab3..36ea373b0 100644 --- a/test/testspriteminimal.c +++ b/test/testspriteminimal.c @@ -20,6 +20,7 @@ #endif #include "SDL.h" +#include "testutils.h" #define WINDOW_WIDTH 640 #define WINDOW_HEIGHT 480 @@ -42,55 +43,6 @@ quit(int rc) exit(rc); } -int -LoadSprite(const char *file) -{ - SDL_Surface *temp; - - /* Load the sprite image */ - temp = SDL_LoadBMP(file); - if (temp == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", file, SDL_GetError()); - return (-1); - } - sprite_w = temp->w; - sprite_h = temp->h; - - /* Set transparent pixel as the pixel at (0,0) */ - if (temp->format->palette) { - SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels); - } else { - switch (temp->format->BitsPerPixel) { - case 15: - SDL_SetColorKey(temp, SDL_TRUE, - (*(Uint16 *) temp->pixels) & 0x00007FFF); - break; - case 16: - SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels); - break; - case 24: - SDL_SetColorKey(temp, SDL_TRUE, - (*(Uint32 *) temp->pixels) & 0x00FFFFFF); - break; - case 32: - SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels); - break; - } - } - - /* Create textures from the image */ - sprite = SDL_CreateTextureFromSurface(renderer, temp); - if (!sprite) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError()); - SDL_FreeSurface(temp); - return (-1); - } - SDL_FreeSurface(temp); - - /* We're ready to roll. :) */ - return (0); -} - void MoveSprites() { @@ -158,7 +110,9 @@ main(int argc, char *argv[]) quit(2); } - if (LoadSprite("icon.bmp") < 0) { + sprite = LoadTexture(renderer, "icon.bmp", SDL_TRUE, &sprite_w, &sprite_h); + + if (sprite == NULL) { quit(2); } diff --git a/test/teststreaming.c b/test/teststreaming.c index 72444f80e..dc3ae61d6 100644 --- a/test/teststreaming.c +++ b/test/teststreaming.c @@ -23,6 +23,7 @@ #endif #include "SDL.h" +#include "testutils.h" #define MOOSEPIC_W 64 #define MOOSEPIC_H 88 @@ -128,6 +129,7 @@ main(int argc, char **argv) { SDL_Window *window; SDL_RWops *handle; + char *filename = NULL; /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); @@ -138,7 +140,13 @@ main(int argc, char **argv) } /* load the moose images */ - handle = SDL_RWFromFile("moose.dat", "rb"); + filename = GetResourceFilename(NULL, "moose.dat"); + if (filename == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory\n"); + return -1; + } + handle = SDL_RWFromFile(filename, "rb"); + SDL_free(filename); if (handle == NULL) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Can't find the file moose.dat !\n"); quit(2); diff --git a/test/testsurround.c b/test/testsurround.c index 168415aca..1537b35fe 100644 --- a/test/testsurround.c +++ b/test/testsurround.c @@ -19,6 +19,7 @@ static int total_channels; static int active_channel; #define SAMPLE_RATE_HZ 48000 +#define QUICK_TEST_TIME_MSEC 100 #define CHANNEL_TEST_TIME_SEC 5 #define MAX_AMPLITUDE SDL_MAX_SINT16 @@ -188,7 +189,11 @@ main(int argc, char *argv[]) SDL_Log("Playing %d Hz test tone on channel: %s\n", sine_freq, get_channel_name(j, total_channels)); /* fill_buffer() will increment the active channel */ - SDL_Delay(CHANNEL_TEST_TIME_SEC * 1000); + if (SDL_getenv("SDL_TESTS_QUICK") != NULL) { + SDL_Delay(QUICK_TEST_TIME_MSEC); + } else { + SDL_Delay(CHANNEL_TEST_TIME_SEC * 1000); + } } SDL_CloseAudioDevice(dev); diff --git a/test/testthread.c b/test/testthread.c index bf201e8e4..ea94dfb2e 100644 --- a/test/testthread.c +++ b/test/testthread.c @@ -91,6 +91,12 @@ main(int argc, char *argv[]) return (1); } + if (SDL_getenv("SDL_TESTS_QUICK") != NULL) { + SDL_Log("Not running slower tests"); + SDL_Quit(); + return 0; + } + while (argv[arg] && *argv[arg] == '-') { if (SDL_strcmp(argv[arg], "--prio") == 0) { testprio = 1; diff --git a/test/testtimer.c b/test/testtimer.c index d696097c8..62c5cd5f9 100644 --- a/test/testtimer.c +++ b/test/testtimer.c @@ -54,6 +54,12 @@ main(int argc, char *argv[]) return (1); } + if (SDL_getenv("SDL_TESTS_QUICK") != NULL) { + SDL_Log("Not running slower tests"); + SDL_Quit(); + return 0; + } + /* Verify SDL_GetTicks* acts monotonically increasing, and not erratic. */ SDL_Log("Sanity-checking GetTicks\n"); for (i = 0; i < 1000; ++i) { diff --git a/test/testutils.c b/test/testutils.c new file mode 100644 index 000000000..e6773ac3a --- /dev/null +++ b/test/testutils.c @@ -0,0 +1,161 @@ +/* +Copyright 1997-2022 Sam Lantinga +Copyright 2022 Collabora Ltd. +SPDX-License-Identifier: Zlib +*/ + +#include "testutils.h" + +#if defined(SDL_FILESYSTEM_OS2) || defined(SDL_FILESYSTEM_WINDOWS) +static const char pathsep[] = "\\"; +#elif defined(SDL_FILESYSTEM_RISCOS) +static const char pathsep[] = "."; +#else +static const char pathsep[] = "/"; +#endif + +/* + * Return the absolute path to def in the SDL_GetBasePath() if possible, or + * the relative path to def on platforms that don't have a working + * SDL_GetBasePath(). Free the result with SDL_free. + * + * Fails and returns NULL if out of memory. + */ +char * +GetNearbyFilename(const char *file) +{ + char *base; + char *path; + + base = SDL_GetBasePath(); + + if (base != NULL) { + SDL_RWops *rw; + size_t len = SDL_strlen(base) + SDL_strlen(pathsep) + SDL_strlen(file) + 1; + + path = SDL_malloc(len); + + if (path == NULL) { + SDL_free(base); + SDL_OutOfMemory(); + return NULL; + } + + SDL_snprintf(path, len, "%s%s%s", base, pathsep, file); + SDL_free(base); + + rw = SDL_RWFromFile(path, "rb"); + if (rw) { + SDL_RWclose(rw); + return path; + } + + /* Couldn't find the file in the base path */ + SDL_free(path); + } + + path = SDL_strdup(file); + if (path == NULL) { + SDL_OutOfMemory(); + } + return path; +} + +/* + * If user_specified is non-NULL, return a copy of it. Free with SDL_free. + * + * Otherwise, return the absolute path to def in the SDL_GetBasePath() if + * possible, or the relative path to def on platforms that don't have a + * working SDL_GetBasePath(). Free the result with SDL_free. + * + * Fails and returns NULL if out of memory. + */ +char * +GetResourceFilename(const char *user_specified, const char *def) +{ + if (user_specified != NULL) { + char *ret = SDL_strdup(user_specified); + + if (ret == NULL) { + SDL_OutOfMemory(); + } + + return ret; + } else { + return GetNearbyFilename(def); + } +} + +/* + * Load the .bmp file whose name is file, from the SDL_GetBasePath() if + * possible or the current working directory if not. + * + * If transparent is true, set the transparent colour from the top left pixel. + * + * If width_out is non-NULL, set it to the texture width. + * + * If height_out is non-NULL, set it to the texture height. + */ +SDL_Texture * +LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent, + int *width_out, int *height_out) +{ + SDL_Surface *temp = NULL; + SDL_Texture *texture = NULL; + char *path; + + path = GetNearbyFilename(file); + + if (path != NULL) { + file = path; + } + + temp = SDL_LoadBMP(file); + if (temp == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError()); + } else { + /* Set transparent pixel as the pixel at (0,0) */ + if (transparent) { + if (temp->format->palette) { + SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *)temp->pixels); + } else { + switch (temp->format->BitsPerPixel) { + case 15: + SDL_SetColorKey(temp, SDL_TRUE, + (*(Uint16 *) temp->pixels) & 0x00007FFF); + break; + case 16: + SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels); + break; + case 24: + SDL_SetColorKey(temp, SDL_TRUE, + (*(Uint32 *) temp->pixels) & 0x00FFFFFF); + break; + case 32: + SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels); + break; + } + } + } + + if (width_out != NULL) { + *width_out = temp->w; + } + + if (height_out != NULL) { + *height_out = temp->h; + } + + texture = SDL_CreateTextureFromSurface(renderer, temp); + if (!texture) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError()); + } + } + if (temp) { + SDL_FreeSurface(temp); + } + if (path) { + SDL_free(path); + } + return texture; +} diff --git a/test/testutils.h b/test/testutils.h new file mode 100644 index 000000000..cf24ca043 --- /dev/null +++ b/test/testutils.h @@ -0,0 +1,17 @@ +/* +Copyright 1997-2022 Sam Lantinga +Copyright 2022 Collabora Ltd. +SPDX-License-Identifier: Zlib +*/ + +#ifndef TESTUTILS_H +#define TESTUTILS_H + +#include "SDL.h" + +SDL_Texture *LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent, + int *width_out, int *height_out); +char *GetNearbyFilename(const char *file); +char *GetResourceFilename(const char *user_specified, const char *def); + +#endif diff --git a/test/testviewport.c b/test/testviewport.c index 0e39d852d..162b31069 100644 --- a/test/testviewport.c +++ b/test/testviewport.c @@ -21,7 +21,7 @@ #include "SDL_test.h" #include "SDL_test_common.h" - +#include "testutils.h" static SDLTest_CommonState *state; @@ -42,55 +42,6 @@ quit(int rc) exit(rc); } -int -LoadSprite(const char *file, SDL_Renderer *renderer) -{ - SDL_Surface *temp; - - /* Load the sprite image */ - temp = SDL_LoadBMP(file); - if (temp == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", file, SDL_GetError()); - return (-1); - } - sprite_w = temp->w; - sprite_h = temp->h; - - /* Set transparent pixel as the pixel at (0,0) */ - if (temp->format->palette) { - SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels); - } else { - switch (temp->format->BitsPerPixel) { - case 15: - SDL_SetColorKey(temp, SDL_TRUE, - (*(Uint16 *) temp->pixels) & 0x00007FFF); - break; - case 16: - SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels); - break; - case 24: - SDL_SetColorKey(temp, SDL_TRUE, - (*(Uint32 *) temp->pixels) & 0x00FFFFFF); - break; - case 32: - SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels); - break; - } - } - - /* Create textures from the image */ - sprite = SDL_CreateTextureFromSurface(renderer, temp); - if (!sprite) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError()); - SDL_FreeSurface(temp); - return (-1); - } - SDL_FreeSurface(temp); - - /* We're ready to roll. :) */ - return (0); -} - void DrawOnViewport(SDL_Renderer * renderer) { @@ -229,7 +180,9 @@ main(int argc, char *argv[]) quit(2); } - if (LoadSprite("icon.bmp", state->renderers[0]) < 0) { + sprite = LoadTexture(state->renderers[0], "icon.bmp", SDL_TRUE, &sprite_w, &sprite_h); + + if (sprite == NULL) { quit(2); } diff --git a/test/versioning.sh b/test/versioning.sh new file mode 100755 index 000000000..3a05c6243 --- /dev/null +++ b/test/versioning.sh @@ -0,0 +1,162 @@ +#!/bin/sh +# Copyright 2022 Collabora Ltd. +# SPDX-License-Identifier: Zlib + +set -eu + +ref_major=$(sed -ne 's/^#define SDL_MAJOR_VERSION *//p' include/SDL_version.h) +ref_minor=$(sed -ne 's/^#define SDL_MINOR_VERSION *//p' include/SDL_version.h) +ref_micro=$(sed -ne 's/^#define SDL_PATCHLEVEL *//p' include/SDL_version.h) +ref_version="${ref_major}.${ref_minor}.${ref_micro}" + +tests=0 +failed=0 + +ok () { + tests=$(( tests + 1 )) + echo "ok - $*" +} + +not_ok () { + tests=$(( tests + 1 )) + echo "not ok - $*" + failed=1 +} + +major=$(sed -ne 's/^SDL_MAJOR_VERSION=//p' configure.ac) +minor=$(sed -ne 's/^SDL_MINOR_VERSION=//p' configure.ac) +micro=$(sed -ne 's/^SDL_MICRO_VERSION=//p' configure.ac) +version="${major}.${minor}.${micro}" + +if [ "$ref_version" = "$version" ]; then + ok "configure.ac $version" +else + not_ok "configure.ac $version disagrees with SDL_version.h $ref_version" +fi + +major=$(sed -ne 's/^set(SDL_MAJOR_VERSION \([0-9]\+\))$/\1/p' CMakeLists.txt) +minor=$(sed -ne 's/^set(SDL_MINOR_VERSION \([0-9]\+\))$/\1/p' CMakeLists.txt) +micro=$(sed -ne 's/^set(SDL_MICRO_VERSION \([0-9]\+\))$/\1/p' CMakeLists.txt) +version="${major}.${minor}.${micro}" + +if [ "$ref_version" = "$version" ]; then + ok "CMakeLists.txt $version" +else + not_ok "CMakeLists.txt $version disagrees with SDL_version.h $ref_version" +fi + +major=$(sed -ne 's/^MAJOR_VERSION *= *//p' Makefile.os2) +minor=$(sed -ne 's/^MINOR_VERSION *= *//p' Makefile.os2) +micro=$(sed -ne 's/^MICRO_VERSION *= *//p' Makefile.os2) +version="${major}.${minor}.${micro}" + +if [ "$ref_version" = "$version" ]; then + ok "Makefile.os2 $version" +else + not_ok "Makefile.os2 $version disagrees with SDL_version.h $ref_version" +fi + +major=$(sed -ne 's/^MAJOR_VERSION *= *//p' Makefile.w32) +minor=$(sed -ne 's/^MINOR_VERSION *= *//p' Makefile.w32) +micro=$(sed -ne 's/^MICRO_VERSION *= *//p' Makefile.w32) +version="${major}.${minor}.${micro}" + +if [ "$ref_version" = "$version" ]; then + ok "Makefile.w32 $version" +else + not_ok "Makefile.w32 $version disagrees with SDL_version.h $ref_version" +fi + +version=$(sed -Ene 's/^[$]SDLVersion = "([0-9.]+)"\r?$/\1/p' build-scripts/winrtbuild.ps1) + +if [ "$ref_version" = "$version" ]; then + ok "winrtbuild.ps1 $version" +else + not_ok "winrtbuild.ps1 $version disagrees with SDL_version.h $ref_version" +fi + +tuple=$(sed -ne 's/^ *FILEVERSION *//p' src/main/windows/version.rc | tr -d '\r') +ref_tuple="${ref_major},${ref_minor},${ref_micro},0" + +if [ "$ref_tuple" = "$tuple" ]; then + ok "version.rc FILEVERSION $tuple" +else + not_ok "version.rc FILEVERSION $tuple disagrees with SDL_version.h $ref_tuple" +fi + +tuple=$(sed -ne 's/^ *PRODUCTVERSION *//p' src/main/windows/version.rc | tr -d '\r') + +if [ "$ref_tuple" = "$tuple" ]; then + ok "version.rc PRODUCTVERSION $tuple" +else + not_ok "version.rc PRODUCTVERSION $tuple disagrees with SDL_version.h $ref_tuple" +fi + +tuple=$(sed -Ene 's/^ *VALUE "FileVersion", "([0-9, ]+)\\0"\r?$/\1/p' src/main/windows/version.rc | tr -d '\r') +ref_tuple="${ref_major}, ${ref_minor}, ${ref_micro}, 0" + +if [ "$ref_tuple" = "$tuple" ]; then + ok "version.rc FileVersion $tuple" +else + not_ok "version.rc FileVersion $tuple disagrees with SDL_version.h $ref_tuple" +fi + +tuple=$(sed -Ene 's/^ *VALUE "ProductVersion", "([0-9, ]+)\\0"\r?$/\1/p' src/main/windows/version.rc | tr -d '\r') + +if [ "$ref_tuple" = "$tuple" ]; then + ok "version.rc ProductVersion $tuple" +else + not_ok "version.rc ProductVersion $tuple disagrees with SDL_version.h $ref_tuple" +fi + +version=$(sed -Ene '/CFBundleShortVersionString/,+1 s/.*(.*)<\/string>.*/\1/p' Xcode/SDL/Info-Framework.plist) + +if [ "$ref_version" = "$version" ]; then + ok "Info-Framework.plist CFBundleShortVersionString $version" +else + not_ok "Info-Framework.plist CFBundleShortVersionString $version disagrees with SDL_version.h $ref_version" +fi + +version=$(sed -Ene '/CFBundleVersion/,+1 s/.*(.*)<\/string>.*/\1/p' Xcode/SDL/Info-Framework.plist) + +if [ "$ref_version" = "$version" ]; then + ok "Info-Framework.plist CFBundleVersion $version" +else + not_ok "Info-Framework.plist CFBundleVersion $version disagrees with SDL_version.h $ref_version" +fi + +# For simplicity this assumes we'll never break ABI before SDL 3. +dylib_compat=$(sed -Ene 's/.*DYLIB_COMPATIBILITY_VERSION = (.*);$/\1/p' Xcode/SDL/SDL.xcodeproj/project.pbxproj) +ref='1.0.0 +1.0.0' + +if [ "$ref" = "$dylib_compat" ]; then + ok "project.pbxproj DYLIB_COMPATIBILITY_VERSION is consistent" +else + not_ok "project.pbxproj DYLIB_COMPATIBILITY_VERSION is inconsistent" +fi + +dylib_cur=$(sed -Ene 's/.*DYLIB_CURRENT_VERSION = (.*);$/\1/p' Xcode/SDL/SDL.xcodeproj/project.pbxproj) + +case "$ref_minor" in + (*[02468]) + major="$(( ref_minor * 100 + 1 ))" + minor="$ref_micro" + ;; + (*) + major="$(( ref_minor * 100 + ref_micro + 1 ))" + minor="0" + ;; +esac + +ref="${major}.${minor}.0 +${major}.${minor}.0" + +if [ "$ref" = "$dylib_cur" ]; then + ok "project.pbxproj DYLIB_CURRENT_VERSION is consistent" +else + not_ok "project.pbxproj DYLIB_CURRENT_VERSION is inconsistent" +fi + +echo "1..$tests" +exit "$failed" diff --git a/test/watcom.mif b/test/watcom.mif new file mode 100644 index 000000000..dbeec5ddd --- /dev/null +++ b/test/watcom.mif @@ -0,0 +1,115 @@ +INCPATH+= -I"../include" +LIBPATH = .. +LIBS = SDL2.lib SDL2test.lib testutils.lib + +#CFLAGS+= -DHAVE_SDL_TTF +#TTFLIBS = SDL2ttf.lib + +CFLAGS+= $(INCPATH) + +TARGETS = testatomic.exe testdisplayinfo.exe testbounds.exe testdraw2.exe & + testdrawchessboard.exe testdropfile.exe testerror.exe testfile.exe & + testfilesystem.exe testgamecontroller.exe testgeometry.exe testgesture.exe & + testhittesting.exe testhotplug.exe testiconv.exe testime.exe testlocale.exe & + testintersections.exe testjoystick.exe testkeys.exe testloadso.exe & + testlock.exe testmessage.exe testoverlay2.exe testplatform.exe & + testpower.exe testsensor.exe testrelative.exe testrendercopyex.exe & + testrendertarget.exe testrumble.exe testscale.exe testsem.exe & + testshader.exe testshape.exe testsprite2.exe testspriteminimal.exe & + teststreaming.exe testthread.exe testtimer.exe testver.exe & + testviewport.exe testwm2.exe torturethread.exe checkkeys.exe & + checkkeysthreads.exe testmouse.exe testgles.exe testgles2.exe & + controllermap.exe testhaptic.exe testqsort.exe testresample.exe & + testaudioinfo.exe testaudiocapture.exe loopwave.exe loopwavequeue.exe & + testsurround.exe testyuv.exe testgl2.exe testvulkan.exe testnative.exe & + testautomation.exe testaudiohotplug.exe testcustomcursor.exe testmultiaudio.exe & + testoffscreen.exe testurl.exe + +noninteractive = & + testatomic.exe & + testerror.exe & + testfilesystem.exe & + testkeys.exe & + testlocale.exe & + testplatform.exe & + testpower.exe & + testqsort.exe & + testthread.exe & + testtimer.exe & + testver.exe + +needs_audio = & + testaudioinfo.exe & + testsurround.exe + +needs_display = & + testbounds.exe & + testdisplayinfo.exe + +TESTS = $(noninteractive) $(needs_audio) $(needs_display) + +# testautomation sources +TASRCS = testautomation.c testautomation_audio.c testautomation_clipboard.c & + testautomation_events.c testautomation_hints.c & + testautomation_keyboard.c testautomation_main.c & + testautomation_mouse.c testautomation_pixels.c & + testautomation_platform.c testautomation_rect.c & + testautomation_render.c testautomation_rwops.c & + testautomation_sdltest.c testautomation_stdlib.c & + testautomation_surface.c testautomation_syswm.c & + testautomation_timer.c testautomation_video.c + +OBJS = $(TARGETS:.exe=.obj) +COBJS = $(CSRCS:.c=.obj) +TAOBJS = $(TASRCS:.c=.obj) +TNOBJS = $(TNSRCS:.c=.obj) + +all: testutils.lib $(TARGETS) + +.c: ../src/test + +.obj.exe: + wlink SYS $(SYSTEM) libpath $(LIBPATH) lib {$(LIBS)} op q op el file {$<} name $@ + +.c.obj: + wcc386 $(CFLAGS) -fo=$^@ $< + +# specials +testautomation.exe: $(TAOBJS) + wlink SYS $(SYSTEM) libpath $(LIBPATH) lib {$(LIBS)} op q op el file {$<} name $@ + +testnative.exe: $(TNOBJS) + wlink SYS $(SYSTEM) libpath $(LIBPATH) lib {$(LIBS)} op q op el file {$<} name $@ + +testoverlay2.exe: testoverlay2.obj testyuv_cvt.obj + wlink SYS $(SYSTEM) libpath $(LIBPATH) lib {$(LIBS)} op q op el file {$<} name $@ + +testyuv.exe: testyuv.obj testyuv_cvt.obj + wlink SYS $(SYSTEM) libpath $(LIBPATH) lib {$(LIBS)} op q op el file {$<} name $@ + +testshader.exe: testshader.obj + wlink SYS $(SYSTEM) libpath $(LIBPATH) lib {$(LIBS) $(GLLIBS)} op q op el file {$<} name $@ + +testime.exe: testime.obj + wlink SYS $(SYSTEM) libpath $(LIBPATH) lib {$(LIBS) $(TTFLIBS)} op q op el file {$<} name $@ + +testutils.lib: testutils.obj + wlib -q -b -n -c -pa -s -t -zld -ii -io $@ $< + +check: .SYMBOLIC $(TESTS) + @set SDL_AUDIODRIVER=dummy + @set SDL_VIDEODRIVER=dummy + @copy "../SDL2.dll" . + @for %exe in ($(TESTS)) do %exe + +check-quick: .SYMBOLIC $(TESTS) + @set SDL_TESTS_QUICK=1 + @set SDL_AUDIODRIVER=dummy + @set SDL_VIDEODRIVER=dummy + @copy "../SDL2.dll" . + @for %exe in ($(TESTS)) do %exe + +clean: .SYMBOLIC + rm -f *.obj *.err +distclean: .SYMBOLIC clean + rm -f *.exe *.lib