From 8391bd6856dad1ad28aa14de19e0240fb4fa2dbe Mon Sep 17 00:00:00 2001 From: slipher Date: Sat, 16 Aug 2025 09:12:58 -0500 Subject: [PATCH 01/36] cmake: don't set CMAKE_FIND_ROOT_PATH in toolchain files When CMAKE_FIND_ROOT_PATH and CMAKE_PREFIX_PATH are both set, cmake concatenates them together, instead of using CMAKE_PREFIX_PATH as a full path like we want. Turns out CMAKE_FIND_ROOT_PATH didn't do anything anyway, so get rid of that. --- cmake/cross-toolchain-mingw32.cmake | 4 +--- cmake/cross-toolchain-mingw64.cmake | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/cmake/cross-toolchain-mingw32.cmake b/cmake/cross-toolchain-mingw32.cmake index 3c97d7a0e6..c33340276b 100644 --- a/cmake/cross-toolchain-mingw32.cmake +++ b/cmake/cross-toolchain-mingw32.cmake @@ -7,10 +7,8 @@ set( CMAKE_C_COMPILER i686-w64-mingw32-gcc ) set( CMAKE_CXX_COMPILER i686-w64-mingw32-g++ ) set( CMAKE_RC_COMPILER i686-w64-mingw32-windres ) -# Target prefix -set( CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32 ) - # Find programs using host paths and headers/libraries using target paths +# FIXME: not respected when cmake invokes pkg-config set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER ) set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY ) set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY ) diff --git a/cmake/cross-toolchain-mingw64.cmake b/cmake/cross-toolchain-mingw64.cmake index fb308a4556..24636132bf 100644 --- a/cmake/cross-toolchain-mingw64.cmake +++ b/cmake/cross-toolchain-mingw64.cmake @@ -7,10 +7,8 @@ set( CMAKE_C_COMPILER x86_64-w64-mingw32-gcc ) set( CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++ ) set( CMAKE_RC_COMPILER x86_64-w64-mingw32-windres ) -# Target prefix -set( CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32 ) - # Find programs using host paths and headers/libraries using target paths +# FIXME: not respected when cmake invokes pkg-config set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER ) set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY ) set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY ) From f31e41566b9944992dacd27cbfdde9510dcab428 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Sat, 16 Nov 2024 20:51:29 +0100 Subject: [PATCH 02/36] cmake: download test deps archive from test/deps if not released yet --- CMakeLists.txt | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 93ff21b2b6..964dd90c75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -454,22 +454,38 @@ if (DEPS_DIR) if (NOT EXISTS ${DEPS_DIR}) file(MAKE_DIRECTORY ${EXTERNAL_DEPS_DIR}) get_filename_component(BASENAME ${DEPS_DIR} NAME) - set(REMOTE "https://dl.unvanquished.net/deps/${BASENAME}${DEPS_EXT}") - message(STATUS "Downloading dependencies from '${REMOTE}'") - file(DOWNLOAD ${REMOTE} ${OBJ_DIR}/${BASENAME}${DEPS_EXT} - SHOW_PROGRESS - STATUS DOWNLOAD_RESULT - LOG DOWNLOAD_LOG - ) - list(GET DOWNLOAD_RESULT 0 DOWNLOAD_STATUS) - list(GET DOWNLOAD_RESULT 1 DOWNLOAD_STRING) + set(DEPS_FILENAME "${BASENAME}${DEPS_EXT}") + + # Download test DEPS archive if DEPS archive isn't available yet. + # This makes possible to get the CI working before releasing the DEPS archive. + foreach(REMOTE_BASEURL https://dl.unvanquished.net/deps;https://dl.unvanquished.net/test/deps) + set(REMOTE "${REMOTE_BASEURL}/${DEPS_FILENAME}") + message(STATUS "Downloading dependencies from '${REMOTE}'") + + file(DOWNLOAD "${REMOTE}" "${OBJ_DIR}/${DEPS_FILENAME}" + SHOW_PROGRESS + STATUS DOWNLOAD_RESULT + LOG DOWNLOAD_LOG + ) + + list(GET DOWNLOAD_RESULT 0 DOWNLOAD_STATUS) + list(GET DOWNLOAD_RESULT 1 DOWNLOAD_STRING) + + if (DOWNLOAD_STATUS EQUAL 0) + break() + else () + message(WARNING "Error downloading '${REMOTE}': + Status code: ${DOWNLOAD_STATUS} + Error string: ${DOWNLOAD_STRING} + Download log: ${DOWNLOAD_LOG}" + ) + endif() + endforeach() + if (NOT DOWNLOAD_STATUS EQUAL 0) - message(FATAL_ERROR "Error downloading '${REMOTE}': - Status code: ${DOWNLOAD_STATUS} - Error string: ${DOWNLOAD_STRING} - Download log: ${DOWNLOAD_LOG}" - ) + message(FATAL_ERROR "Failed to download '${DEPS_FILENAME}'") endif() + message(STATUS "Download completed successfully") # Extract the downloaded archive From a49f67c0ab719df2cb33f98789ed4818ecc9187a Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 18 Nov 2024 19:01:46 +0100 Subject: [PATCH 03/36] cmake: copy all macOS frameworks from deps --- CMakeLists.txt | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 964dd90c75..12f35a13c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1078,11 +1078,16 @@ if (DEPS_DIR AND (BUILD_CLIENT OR BUILD_TTY_CLIENT OR BUILD_SERVER OR BUILD_DUMM # Mac requires some libraries from external_deps if (APPLE) - add_custom_command(TARGET runtime_deps PRE_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory - ${DEPS_DIR}/SDL2.framework - ${FULL_OUTPUT_DIR}/SDL2.framework - ) + file(GLOB RUNTIME_FRAMEWORKS ${DEPS_DIR}/lib/*.framework) + foreach(RUNTIME_FRAMEWORK ${RUNTIME_FRAMEWORKS}) + get_filename_component(RUNTIME_FRAMEWORK_NAME ${RUNTIME_FRAMEWORK} NAME) + add_custom_command(TARGET runtime_deps PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${RUNTIME_FRAMEWORK} + ${FULL_OUTPUT_DIR}/${RUNTIME_FRAMEWORK_NAME} + ) + endforeach() + file(GLOB RUNTIME_LIBS ${DEPS_DIR}/lib/*.dylib) foreach(RUNTIME_LIB ${RUNTIME_LIBS}) add_custom_command(TARGET runtime_deps PRE_BUILD From a569b64e20fd8f6f7d58f09d3c342f86deee1259 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 18 Nov 2024 19:15:04 +0100 Subject: [PATCH 04/36] cmake,external_deps: install and look for macos frameworks in lib/ --- CMakeLists.txt | 2 +- external_deps/build.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 12f35a13c9..f2ef9c2f6a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -502,7 +502,7 @@ if (DEPS_DIR) # Add to paths set(CMAKE_FIND_ROOT_PATH ${DEPS_DIR} ${CMAKE_FIND_ROOT_PATH}) set(CMAKE_INCLUDE_PATH ${DEPS_DIR} ${DEPS_DIR}/include ${CMAKE_INCLUDE_PATH}) - set(CMAKE_FRAMEWORK_PATH ${DEPS_DIR} ${CMAKE_FRAMEWORK_PATH}) + set(CMAKE_FRAMEWORK_PATH ${DEPS_DIR}/lib ${CMAKE_FRAMEWORK_PATH}) set(CMAKE_PREFIX_PATH ${DEPS_DIR} ${CMAKE_PREFIX_PATH}) if (DAEMON_PARENT_SCOPE_DIR) # Also set parent scope so the top level CMakeLists can find precompiled deps diff --git a/external_deps/build.sh b/external_deps/build.sh index 3b2f5ebbb0..9180f26ce1 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -362,8 +362,8 @@ build_sdl2() { cp "${sdl2_lib_dir}/"*.dll "${PREFIX}/SDL2/${sdl2_lib_dir}" ;; macos-*-*) - rm -rf "${PREFIX}/SDL2.framework" - cp -R "SDL2.framework" "${PREFIX}" + rm -rf "${PREFIX}/lib/SDL2.framework" + cp -R "SDL2.framework" "${PREFIX}/lib" ;; *) cd "${dir_name}" From d058a1a4581b73080043148475733ce438bc879a Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Wed, 13 Aug 2025 19:05:17 +0200 Subject: [PATCH 05/36] external_deps: fix DMG mounting on macOS, the build folder may not be on a filesystem allowing that --- external_deps/build.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/external_deps/build.sh b/external_deps/build.sh index 9180f26ce1..2c7a09806e 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -108,11 +108,11 @@ extract() { "${SCRIPT_DIR}/cygtar.py" -xjf "${1}" -C "${2}" ;; *.dmg) - mkdir -p "${2}-dmg" - hdiutil attach -mountpoint "${2}-dmg" "${1}" - cp -R "${2}-dmg/"* "${2}/" - hdiutil detach "${2}-dmg" - rmdir "${2}-dmg" + local dmg_temp_dir="$(mktemp -d)" + hdiutil attach -mountpoint "${dmg_temp_dir}" "${1}" + cp -R "${dmg_temp_dir}/"* "${2}/" + hdiutil detach "${dmg_temp_dir}" + rmdir "${dmg_temp_dir}" ;; *) log ERROR "Unknown archive type for ${1}" From 7d107bd9d60ce6476b3dc5f0d320f3d67c20367b Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Sat, 19 Jul 2025 15:26:15 +0200 Subject: [PATCH 06/36] external_deps: the NaCl runtime is only buildable on linux-amd64 --- external_deps/build.sh | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/external_deps/build.sh b/external_deps/build.sh index 2c7a09806e..6774e17934 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -1186,11 +1186,11 @@ all_windows_i686_mingw_packages="${base_windows_amd64_mingw_packages}" base_macos_amd64_default_packages='pkgconfig nasm gmp nettle sdl2 glew png jpeg webp openal ogg vorbis opus opusfile naclsdk' all_macos_amd64_default_packages="${base_macos_amd64_default_packages}" -base_linux_amd64_default_packages='naclsdk naclruntime' -all_linux_amd64_default_packages='zlib gmp nettle curl sdl2 glew png jpeg webp openal ogg vorbis opus opusfile naclsdk naclruntime' +base_linux_i686_default_packages='naclsdk' +all_linux_i686_default_packages='zlib gmp nettle curl sdl2 glew png jpeg webp openal ogg vorbis opus opusfile naclsdk' -base_linux_i686_default_packages="${base_linux_amd64_default_packages}" -all_linux_i686_default_packages="${all_linux_amd64_default_packages}" +base_linux_amd64_default_packages="${base_linux_i686_default_packages} naclruntime" +all_linux_amd64_default_packages="${all_linux_i686_default_packages} naclruntime" base_linux_arm64_default_packages='naclsdk' all_linux_arm64_default_packages='zlib gmp nettle curl sdl2 glew png jpeg webp openal ogg vorbis opus opusfile naclsdk' @@ -1247,10 +1247,13 @@ errorHelp() { \tall: same linux-amd64-default: - linux-i686-default: \tbase: ${base_linux_amd64_default_packages} \tall: ${all_linux_amd64_default_packages} + linux-i686-default: + \tbase: ${base_linux_i686_default_packages} + \tall: ${all_linux_i686_default_packages} + linux-arm64-default: linux-armhf-default: \tbase: ${base_linux_arm64_default_packages} From 00180dbe3224212518294fa46284798dc42d2e6a Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Sat, 19 Jul 2025 23:12:32 +0200 Subject: [PATCH 07/36] =?UTF-8?q?external=5Fdeps:=20add=20the=20missing=20?= =?UTF-8?q?=E2=80=9Cncurses=E2=80=9D=20to=20=E2=80=9Call=E2=80=9D=20linux?= =?UTF-8?q?=20dependencies?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- external_deps/build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/external_deps/build.sh b/external_deps/build.sh index 6774e17934..b70ef0e23d 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -1187,13 +1187,13 @@ base_macos_amd64_default_packages='pkgconfig nasm gmp nettle sdl2 glew png jpeg all_macos_amd64_default_packages="${base_macos_amd64_default_packages}" base_linux_i686_default_packages='naclsdk' -all_linux_i686_default_packages='zlib gmp nettle curl sdl2 glew png jpeg webp openal ogg vorbis opus opusfile naclsdk' +all_linux_i686_default_packages='zlib gmp nettle curl sdl2 glew png jpeg webp openal ogg vorbis opus opusfile ncurses naclsdk' base_linux_amd64_default_packages="${base_linux_i686_default_packages} naclruntime" all_linux_amd64_default_packages="${all_linux_i686_default_packages} naclruntime" base_linux_arm64_default_packages='naclsdk' -all_linux_arm64_default_packages='zlib gmp nettle curl sdl2 glew png jpeg webp openal ogg vorbis opus opusfile naclsdk' +all_linux_arm64_default_packages='zlib gmp nettle curl sdl2 glew png jpeg webp openal ogg vorbis opus opusfile ncurses naclsdk' base_linux_armhf_default_packages="${base_linux_arm64_default_packages}" all_linux_armhf_default_packages="${all_linux_arm64_default_packages}" From 8266723271b15c62f961bdf17e5ed05bc57283bb Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 11 Nov 2024 01:00:00 +0100 Subject: [PATCH 08/36] external_deps: fix JPEG and OpenAL download --- external_deps/build.sh | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/external_deps/build.sh b/external_deps/build.sh index b70ef0e23d..8aed796237 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -445,7 +445,7 @@ build_jpeg() { local archive_name="${dir_name}.tar.gz" download_extract jpeg "${archive_name}" \ - "${JPEG_BASEURL}/${JPEG_VERSION}/${archive_name}" + "${JPEG_BASEURL}/download/${JPEG_VERSION}/${archive_name}" "${download_only}" && return @@ -529,14 +529,34 @@ build_webp() { # Build OpenAL build_openal() { + # On OpenAL website, Windows binaries are on: + # https://openal-soft.org/openal-binaries/openal-soft-1.24.3-bin.zip + # and sources are on: + # https://openal-soft.org/openal-releases/openal-soft-1.24.3.tar.bz2 + + # But on GitHub Windows binaries are on: + # https://github.com/kcat/openal-soft/releases/download/1.24.3/openal-soft-1.24.3-bin.zip + # and sources are on: + # https://github.com/kcat/openal-soft/archive/refs/tags/1.24.3.tar.gz + + # They contain the same content, but GitHub is more reliable so we use the tar.gz archive. + # We mirror it as openal-soft-1.24.3.tar.gz for convenience. + + # There is no tar.bz2 uploaded to GitHub anymore, so we cannot use GitHub as a mirror + # for the OpenAL website. + case "${PLATFORM}" in windows-*-*) local dir_name="openal-soft-${OPENAL_VERSION}-bin" local archive_name="${dir_name}.zip" + local github_archive_name="${archive_name}" + local github_subdir='releases/download' ;; macos-*-*|linux-*-*) local dir_name="openal-soft-${OPENAL_VERSION}" - local archive_name="${dir_name}.tar.bz2" + local archive_name="${dir_name}.tar.gz" + local github_archive_name="${OPENAL_VERSION}.tar.gz" + local github_subdir='archive/refs/tags' local openal_cmake_call=(cmake -S . -B . -DCMAKE_INSTALL_PREFIX="${PREFIX}" \ -DCMAKE_C_FLAGS="${CFLAGS}" -DCMAKE_CXX_FLAGS="${CXXFLAGS}" \ -DCMAKE_BUILD_TYPE=Release -DALSOFT_EXAMPLES=OFF) @@ -547,8 +567,7 @@ build_openal() { esac download_extract openal "${archive_name}" \ - "${OPENAL_BASEURL}/${archive_name}" \ - "https://github.com/kcat/openal-soft/releases/download/${OPENAL_VERSION}/${archive_name}" \ + "${OPENAL_BASEURL}/${github_subdir}/${OPENAL_VERSION}/${github_archive_name}" "${download_only}" && return From b47d2af2948a51fd73b7684810c4afddbac1ba77 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 18 Nov 2024 03:04:42 +0100 Subject: [PATCH 09/36] external_deps: fix SDL2 windows build --- external_deps/build.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/external_deps/build.sh b/external_deps/build.sh index 8aed796237..021f55b492 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -1024,6 +1024,13 @@ build_install() { ;; esac + case "${PLATFORM}" in + windows-*-*) + # CMake looks for libSDL2.a and aborts if missing if this file exists: + rm -rf "${PKG_PREFIX}/lib/cmake/SDL2/SDL2staticTargets.cmake" + ;; + esac + # Remove empty directories find "${PKG_PREFIX}/" -mindepth 1 -type d -empty -delete } From 4e4f48ce3d1366202819dcd833f731b75e408ebf Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Sun, 10 Nov 2024 15:54:34 +0100 Subject: [PATCH 10/36] =?UTF-8?q?external=5Fdeps:=20introduce=20=E2=80=9Cc?= =?UTF-8?q?make=5Fbuild=E2=80=9D=20and=20=E2=80=9Cconfigure=5Fbuild?= =?UTF-8?q?=E2=80=9D=20wrappers=20and=20use=20them?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: slipher --- external_deps/build.sh | 338 +++++++++++++++++++++++++++++------------ 1 file changed, 241 insertions(+), 97 deletions(-) diff --git a/external_deps/build.sh b/external_deps/build.sh index 021f55b492..b71999a290 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -70,7 +70,9 @@ CXX='false' LD='ld' AR='ar' RANLIB='ranlib' -CONFIGURE_SHARED=(--disable-shared --enable-static) +LIBS_SHARED='OFF' +LIBS_STATIC='ON' +CMAKE_TOOLCHAIN='' # Always reset flags, we heavily cross-compile and must not inherit any stray flag # from environment. CFLAGS='' @@ -161,6 +163,82 @@ download_extract() { extract "${tarball_file}" "${extract_dir}" } +configure_build() { + local configure_args=() + + if [ "${LIBS_SHARED}" = 'ON' ] + then + configure_args+=(--enable-shared) + else + configure_args+=(--disable-shared) + fi + + if [ "${LIBS_STATIC}" = 'ON' ] + then + configure_args+=(--enable-static) + else + configure_args+=(--disable-static) + fi + + # Workaround macOS bash limitation. + if [ -n "${1:-}" ] + then + configure_args+=("${@}") + fi + + ./configure \ + --host="${HOST}" \ + --prefix="${PREFIX}" \ + --libdir="${PREFIX}/lib" \ + "${configure_args[@]}" + + make + make install +} + +get_compiler_name() { + echo "${1}" +} + +get_compiler_arg1() { + shift + + # Check for ${@} not being empty to workaround a macOS bash limitation. + if [ -n "${1:-}" ] + then + echo "${@}" + fi +} + +cmake_build() { + local cmake_args=() + + cmake_args+=(-DCMAKE_C_COMPILER="$(get_compiler_name ${CC})") + cmake_args+=(-DCMAKE_CXX_COMPILER="$(get_compiler_name ${CXX})") + cmake_args+=(-DCMAKE_C_COMPILER_ARG1="$(get_compiler_arg1 ${CC})") + cmake_args+=(-DCMAKE_CXX_COMPILER_ARG1="$(get_compiler_arg1 ${CXX})") + cmake_args+=(-DCMAKE_C_FLAGS="${CFLAGS}") + cmake_args+=(-DCMAKE_CXX_FLAGS="${CXXFLAGS}") + cmake_args+=(-DCMAKE_EXE_LINKER_FLAGS="${LDFLAGS}") + + # Check for ${@} not being empty to workaround a macOS bash limitation. + if [ -n "${1:-}" ] + then + cmake_args+=("${@}") + fi + + cmake -S . -B build \ + -DCMAKE_TOOLCHAIN_FILE="${CMAKE_TOOLCHAIN}" \ + -DCMAKE_BUILD_TYPE='Release' \ + -DCMAKE_PREFIX_PATH="${PREFIX}" \ + -DCMAKE_INSTALL_PREFIX="${PREFIX}" \ + -DBUILD_SHARED_LIBS="${LIBS_SHARED}" \ + "${cmake_args[@]}" + + cmake --build build + cmake --install build --strip +} + # Build pkg-config # Still needed, at least on macos, for opusfile build_pkgconfig() { @@ -173,10 +251,10 @@ build_pkgconfig() { "${download_only}" && return cd "${dir_name}" - # The default -O2 is dropped when there's user-provided CFLAGS. - CFLAGS="${CFLAGS} -O2 -Wno-error=int-conversion" ./configure --host="${HOST}" --prefix="${PREFIX}" --libdir="${PREFIX}/lib" --with-internal-glib - make - make install + + CFLAGS="${CFLAGS} -Wno-error=int-conversion" \ + configure_build \ + --with-internal-glib } # Build NASM @@ -213,16 +291,16 @@ build_zlib() { "${download_only}" && return cd "${dir_name}" + case "${PLATFORM}" in windows-*-*) LOC="${CFLAGS}" make -f win32/Makefile.gcc PREFIX="${HOST}-" make -f win32/Makefile.gcc install BINARY_PATH="${PREFIX}/bin" LIBRARY_PATH="${PREFIX}/lib" INCLUDE_PATH="${PREFIX}/include" SHARED_MODE=1 ;; *) - # The default -O3 is dropped when there's user-provided CFLAGS. - CFLAGS="${CFLAGS} -O3" ./configure --prefix="${PREFIX}" --libdir="${PREFIX}/lib" --static --const - make - make install + CFLAGS="${CFLAGS} -DZLIB_CONST" \ + cmake_build \ + -DZLIB_BUILD_EXAMPLES=OFF ;; esac } @@ -239,7 +317,6 @@ build_gmp() { "${download_only}" && return - cd "${dir_name}" case "${PLATFORM}" in windows-*-msvc) # Configure script gets confused if we override the compiler. Shouldn't @@ -251,19 +328,22 @@ build_gmp() { ;; esac - # The default -O2 is dropped when there's user-provided CFLAGS. + local gmp_configure_args=() + case "${PLATFORM}" in macos-*-*) # The assembler objects are incompatible with PIE - CFLAGS="${CFLAGS} -O2" ./configure --host="${HOST}" --prefix="${PREFIX}" --libdir="${PREFIX}/lib" "${CONFIGURE_SHARED[@]}" --disable-assembly + gmp_configure_args+=(--disable-assembly) ;; *) - CFLAGS="${CFLAGS} -O2" ./configure --host="${HOST}" --prefix="${PREFIX}" --libdir="${PREFIX}/lib" "${CONFIGURE_SHARED[@]}" ;; esac - make - make install + cd "${dir_name}" + + configure_build \ + "${gmp_configure_args[@]}" + case "${PLATFORM}" in windows-*-msvc) export CC="${CC_BACKUP}" @@ -284,10 +364,8 @@ build_nettle() { "${download_only}" && return cd "${dir_name}" - # The default -O2 is dropped when there's user-provided CFLAGS. - CFLAGS="${CFLAGS} -O2" ./configure --host="${HOST}" --prefix="${PREFIX}" --libdir="${PREFIX}/lib" "${CONFIGURE_SHARED[@]}" - make - make install + + configure_build } # Build cURL @@ -302,10 +380,34 @@ build_curl() { "${download_only}" && return cd "${dir_name}" - # The user-provided CFLAGS doesn't drop the default -O2 - ./configure --host="${HOST}" --prefix="${PREFIX}" --libdir="${PREFIX}/lib" --without-ssl --without-libssh2 --without-librtmp --without-libidn2 --without-brotli --without-zstd --disable-file --disable-ldap --disable-crypto-auth --disable-gopher --disable-ftp --disable-tftp --disable-dict --disable-imap --disable-mqtt --disable-smtp --disable-pop3 --disable-telnet --disable-rtsp --disable-threaded-resolver --disable-alt-svc "${CONFIGURE_SHARED[@]}" - make - make install + + cmake_build \ + -DBUILD_CURL_EXE=OFF \ + -DBUILD_TESTING=OFF \ + -DENABLE_CURL_MANUAL=OFF \ + -DENABLE_THREADED_RESOLVER=OFF \ + -DENABLE_UNIX_SOCKETS=OFF \ + -DUSE_HTTPSRR=OFF \ + -DUSE_LIBIDN2=OFF \ + -DUSE_LIBRTMP=OFF \ + -DUSE_MSH3=OFF \ + -DUSE_NGHTTP2=OFF \ + -DUSE_NGTCP2=OFF \ + -DUSE_OPENSSL_QUIC=OFF \ + -DUSE_QUICHE=OFF \ + -DUSE_WIN32_IDN=OFF \ + -DCURL_BROTLI=OFF \ + -DCURL_ZLIB=OFF \ + -DCURL_ZSTD=OFF \ + -DCURL_ENABLE_SSL=OFF \ + -DCURL_USE_GSSAPI=OFF \ + -DCURL_USE_LIBPSL=OFF \ + -DCURL_USE_LIBSSH=OFF \ + -DCURL_USE_LIBSSH2=OFF \ + -DCURL_USE_MBEDTLS=OFF \ + -DCURL_USE_OPENSSL=OFF \ + -DCURL_USE_WOLFSSL=OFF \ + -DHTTP_ONLY=ON # Implies all CURL_DISABLE_xxx options except HTTP } # Build SDL2 @@ -367,10 +469,9 @@ build_sdl2() { ;; *) cd "${dir_name}" - # The default -O3 is dropped when there's user-provided CFLAGS. - CFLAGS="${CFLAGS} -O3" ./configure --host="${HOST}" --prefix="${PREFIX}" --libdir="${PREFIX}/lib" "${CONFIGURE_SHARED[@]}" - make - make install + + cmake_build + # Workaround for an SDL2 CMake bug, we need to provide # a bin/ directory even when nothing is used from it. mkdir -p "${PREFIX}/bin" @@ -392,6 +493,7 @@ build_glew() { "${download_only}" && return cd "${dir_name}" + # env hack: CFLAGS.EXTRA is populated with some flags, which are sometimess necessary for # compilation, in the makefile with +=. If CFLAGS.EXTRA is set on the command line, those # += will be ignored. But if it is set via the environment, the two sources are actually @@ -433,10 +535,10 @@ build_png() { "${download_only}" && return cd "${dir_name}" - # The default -O2 is dropped when there's user-provided CFLAGS. - CFLAGS="${CFLAGS} -O2" ./configure --host="${HOST}" --prefix="${PREFIX}" --libdir="${PREFIX}/lib" "${CONFIGURE_SHARED[@]}" - make - make install + + configure_build \ + --disable-tests \ + --disable-tools } # Build JPEG @@ -460,7 +562,7 @@ build_jpeg() { local SYSTEM_NAME='Linux' ;; *) - # Other platforms can build but we need need to explicitly + # Other platforms can build but we need to explicitly # set CMAKE_SYSTEM_NAME for CMAKE_CROSSCOMPILING to be set # and CMAKE_SYSTEM_PROCESSOR to not be ignored by cmake. log ERROR 'Unsupported platform for JPEG' @@ -489,25 +591,28 @@ build_jpeg() { ;; esac - local jpeg_cmake_call=(cmake -S . -B build -DCMAKE_INSTALL_PREFIX="${PREFIX}" \ - -DCMAKE_C_FLAGS="${CFLAGS}" -DCMAKE_CXX_FLAGS="${CXXFLAGS}" \ - -DCMAKE_SYSTEM_NAME="${SYSTEM_NAME}" -DCMAKE_SYSTEM_PROCESSOR="${SYSTEM_PROCESSOR}" \ - -DWITH_JPEG8=1) + local jpeg_cmake_args=() - cd "${dir_name}" case "${PLATFORM}" in - windows-*-mingw) - "${jpeg_cmake_call[@]}" -DCMAKE_TOOLCHAIN_FILE="${SCRIPT_DIR}/../cmake/cross-toolchain-mingw${BITNESS}.cmake" -DENABLE_SHARED=0 - ;; - windows-*-msvc) - "${jpeg_cmake_call[@]}" -DCMAKE_TOOLCHAIN_FILE="${SCRIPT_DIR}/../cmake/cross-toolchain-mingw${BITNESS}.cmake" -DENABLE_SHARED=1 + windows-*-*) ;; *) - "${jpeg_cmake_call[@]}" -DENABLE_SHARED=0 + # Workaround for: undefined reference to `log10' + # The CMakeLists.txt file only does -lm if UNIX, + # but UNIX may not be true on Linux. + jpeg_cmake_args+=(-DUNIX=True) ;; esac - make -C build - make -C build install + + cd "${dir_name}" + + cmake_build \ + -DENABLE_SHARED="${LIBS_SHARED}" \ + -DENABLE_STATIC="${LIBS_STATIC}" \ + -DCMAKE_SYSTEM_NAME="${SYSTEM_NAME}" \ + -DCMAKE_SYSTEM_PROCESSOR="${SYSTEM_PROCESSOR}" \ + -DWITH_JPEG8=1 \ + "${jpeg_cmake_args[@]}" } # Build WebP @@ -521,10 +626,20 @@ build_webp() { "${download_only}" && return cd "${dir_name}" - # The default -O2 is dropped when there's user-provided CFLAGS. - CFLAGS="${CFLAGS} -O2" ./configure --host="${HOST}" --prefix="${PREFIX}" --libdir="${PREFIX}/lib" --disable-libwebpdemux "${CONFIGURE_SHARED[@]}" - make - make install + + # WEBP_LINK_STATIC is ON by default + + cmake_build \ + -DWEBP_BUILD_ANIM_UTILS=OFF \ + -DWEBP_BUILD_CWEBP=OFF \ + -DWEBP_BUILD_DWEBP=OFF \ + -DWEBP_BUILD_EXTRAS=OFF \ + -DWEBP_BUILD_GIF2WEBP=OFF \ + -DWEBP_BUILD_IMG2WEBP=OFF \ + -DWEBP_BUILD_LIBWEBPMUX=OFF \ + -DWEBP_BUILD_VWEBP=OFF \ + -DWEBP_BUILD_WEBPINFO=OFF \ + -DWEBP_BUILD_WEBPMUX=OFF } # Build OpenAL @@ -552,17 +667,11 @@ build_openal() { local github_archive_name="${archive_name}" local github_subdir='releases/download' ;; - macos-*-*|linux-*-*) + *) local dir_name="openal-soft-${OPENAL_VERSION}" local archive_name="${dir_name}.tar.gz" local github_archive_name="${OPENAL_VERSION}.tar.gz" local github_subdir='archive/refs/tags' - local openal_cmake_call=(cmake -S . -B . -DCMAKE_INSTALL_PREFIX="${PREFIX}" \ - -DCMAKE_C_FLAGS="${CFLAGS}" -DCMAKE_CXX_FLAGS="${CXXFLAGS}" \ - -DCMAKE_BUILD_TYPE=Release -DALSOFT_EXAMPLES=OFF) - ;; - *) - log ERROR 'Unsupported platform for OpenAL' ;; esac @@ -571,6 +680,8 @@ build_openal() { "${download_only}" && return + local openal_cmake_args=(-DALSOFT_EXAMPLES=OFF) + case "${PLATFORM}" in windows-*-*) cd "${dir_name}" @@ -588,16 +699,25 @@ build_openal() { ;; macos-*-*) cd "${dir_name}" - "${openal_cmake_call[@]}" - make - make install + + cmake_build \ + -DLIBTYPE=SHARED \ + "${openal_cmake_args[@]}" + install_name_tool -id "@rpath/libopenal.${OPENAL_VERSION}.dylib" "${PREFIX}/lib/libopenal.${OPENAL_VERSION}.dylib" ;; - linux-*-*) + *) cd "${dir_name}" - "${openal_cmake_call[@]}" -DLIBTYPE=STATIC - make - make install + + cmake_build \ + -DLIBTYPE=STATIC \ + "${openal_cmake_args[@]}" + ;; + esac + + case "${PLATFORM}" in + macos-*-*) + install_name_tool -id "@rpath/libopenal.${OPENAL_VERSION}.dylib" "${PREFIX}/lib/libopenal.${OPENAL_VERSION}.dylib" ;; esac } @@ -613,13 +733,12 @@ build_ogg() { "${download_only}" && return cd "${dir_name}" + # This header breaks the vorbis and opusfile Mac builds cat <(echo '#include ') include/ogg/os_types.h > os_types.tmp mv os_types.tmp include/ogg/os_types.h - # The user-provided CFLAGS doesn't drop the default -O2 - ./configure --host="${HOST}" --prefix="${PREFIX}" --libdir="${PREFIX}/lib" "${CONFIGURE_SHARED[@]}" - make - make install + + configure_build } # Build Vorbis @@ -633,10 +752,18 @@ build_vorbis() { "${download_only}" && return cd "${dir_name}" - # The user-provided CFLAGS doesn't drop the default -O3 - ./configure --host="${HOST}" --prefix="${PREFIX}" --libdir="${PREFIX}/lib" "${CONFIGURE_SHARED[@]}" --disable-examples - make - make install + + case "${PLATFORM}" in + windows-*-msvc) + # Workaround a build issue on MinGW: + # See: https://github.com/microsoft/vcpkg/issues/22990 + # and: https://github.com/microsoft/vcpkg/pull/23761 + ls win32/vorbis.def win32/vorbisenc.def win32/vorbisfile.def \ + | xargs -I{} -P3 sed -e 's/LIBRARY//' -i {} + ;; + esac + + cmake_build } # Build Opus @@ -649,19 +776,23 @@ build_opus() { "${download_only}" && return - cd "${dir_name}" - # The default -O2 is dropped when there's user-provided CFLAGS. + local opus_cmake_args=() + case "${PLATFORM}" in windows-*-*) - # With MinGW _FORTIFY_SOURCE (added by configure) can only by used with -fstack-protector enabled. - CFLAGS="${CFLAGS} -O2 -D_FORTIFY_SOURCE=0" ./configure --host="${HOST}" --prefix="${PREFIX}" --libdir="${PREFIX}/lib" "${CONFIGURE_SHARED[@]}" - ;; - *) - CFLAGS="${CFLAGS} -O2" ./configure --host="${HOST}" --prefix="${PREFIX}" --libdir="${PREFIX}/lib" "${CONFIGURE_SHARED[@]}" + # With MinGW, we would get this error: + # undefined reference to `__stack_chk_guard' + opus_cmake_args+=(-DOPUS_FORTIFY_SOURCE=OFF -DOPUS_STACK_PROTECTOR=OFF) ;; esac - make - make install + + cd "${dir_name}" + + cmake_build \ + -DOPUS_BUILD_PROGRAMS=OFF \ + -DOPUS_BUILD_TESTING=OFF \ + -DOPUS_FLOAT_APPROX=ON \ + "${opus_cmake_args[@]}" } # Build OpusFile @@ -675,10 +806,9 @@ build_opusfile() { "${download_only}" && return cd "${dir_name}" - # The default -O2 is dropped when there's user-provided CFLAGS. - CFLAGS="${CFLAGS} -O2" ./configure --host="${HOST}" --prefix="${PREFIX}" --libdir="${PREFIX}/lib" "${CONFIGURE_SHARED[@]}" --disable-http - make - make install + + configure_build \ + --disable-http } # Build ncurses @@ -693,11 +823,17 @@ build_ncurses() { "${download_only}" && return cd "${dir_name}" - # The default -O2 is dropped when there's user-provided CFLAGS. + + # Brutally disable writing to database + cp /dev/null misc/run_tic.in # Configure terminfo search dirs based on the ones used in Debian. By default it will only look in (only) the install directory. - CFLAGS="${CFLAGS} -O2" ./configure --host="${HOST}" --prefix="${PREFIX}" --libdir="${PREFIX}/lib" --enable-widec "${CONFIGURE_SHARED[@]}" --with-terminfo-dirs=/etc/terminfo:/lib/terminfo --with-default-terminfo-dir=/usr/share/terminfo - make - make install + local strip="${HOST/-unknown-/-}-strip" + configure_build \ + --with-strip-program="${strip}" \ + --without-progs \ + --enable-widec \ + --with-terminfo-dirs=/etc/terminfo:/lib/terminfo \ + --with-default-terminfo-dir=/usr/share/terminfo } # "Builds" (downloads) the WASI SDK @@ -1057,8 +1193,10 @@ build_wipe() { # Common setup code common_setup() { HOST="${2}" + "common_setup_${1}" common_setup_arch + DOWNLOAD_DIR="${WORK_DIR}/download_cache" PKG_BASEDIR="${PLATFORM}_${DEPS_VERSION}" BUILD_BASEDIR="build-${PKG_BASEDIR}" @@ -1069,10 +1207,12 @@ common_setup() { PKG_CONFIG_PATH="${PREFIX}/lib/pkgconfig" CPPFLAGS+=" -I${PREFIX}/include" LDFLAGS+=" -L${PREFIX}/lib" + mkdir -p "${DOWNLOAD_DIR}" mkdir -p "${PREFIX}/bin" mkdir -p "${PREFIX}/include" mkdir -p "${PREFIX}/lib" + export CC CXX LD AR RANLIB PKG_CONFIG PKG_CONFIG_PATH PATH CFLAGS CXXFLAGS CPPFLAGS LDFLAGS } @@ -1108,24 +1248,27 @@ common_setup_arch() { # Lua does use this one, which results in compiler warnings. But this is OK because # the Windows build of Lua is only used in developer gamelogic builds, and Microsoft # supports %lld since Visual Studio 2013. Also we don't build Lua anymore. -common_setup_msvc() { - CONFIGURE_SHARED=(--enable-shared --disable-static) - # Libtool bug prevents -static-libgcc from being set in LDFLAGS - CC="${HOST}-gcc -static-libgcc" - CXX="${HOST}-g++ -static-libgcc" +common_setup_windows() { LD="${HOST}-ld" AR="${HOST}-ar" RANLIB="${HOST}-ranlib" CFLAGS+=' -D__USE_MINGW_ANSI_STDIO=0' + CMAKE_TOOLCHAIN="${SCRIPT_DIR}/../cmake/cross-toolchain-mingw${BITNESS}.cmake" +} + +common_setup_msvc() { + LIBS_SHARED='ON' + LIBS_STATIC='OFF' + # Libtool bug prevents -static-libgcc from being set in LDFLAGS + CC="${HOST}-gcc -static-libgcc" + CXX="${HOST}-g++ -static-libgcc" + common_setup_windows } common_setup_mingw() { CC="${HOST}-gcc" CXX="${HOST}-g++" - LD="${HOST}-ld" - AR="${HOST}-ar" - RANLIB="${HOST}-ranlib" - CFLAGS+=' -D__USE_MINGW_ANSI_STDIO=0' + common_setup_windows } common_setup_macos() { @@ -1328,6 +1471,7 @@ CURL="$(command -v curl)" || log ERROR "Command 'curl' not found" # Enable parallel build export MAKEFLAGS="-j`nproc 2> /dev/null || sysctl -n hw.ncpu 2> /dev/null || echo 1`" export SCONSFLAGS="${MAKEFLAGS}" +export CMAKE_BUILD_PARALLEL_LEVEL="$(nproc 2> /dev/null || sysctl -n hw.ncpu 2> /dev/null || echo 1)" # Setup platform platform="${1}"; shift From a78c7efc25fbd49337d43024389e11ba9a0c48c4 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 11 Nov 2024 00:01:36 +0100 Subject: [PATCH 11/36] external_deps: use -O3 and -fPIC for all packages O3 because we use CMake Release build type that sets O3 anyway, so things are consistent. --- external_deps/build.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/external_deps/build.sh b/external_deps/build.sh index b71999a290..9055ae72dd 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -75,10 +75,10 @@ LIBS_STATIC='ON' CMAKE_TOOLCHAIN='' # Always reset flags, we heavily cross-compile and must not inherit any stray flag # from environment. -CFLAGS='' -CXXFLAGS='' CPPFLAGS='' -LDFLAGS='' +CFLAGS='-O3 -fPIC' +CXXFLAGS='-O3 -fPIC' +LDFLAGS='-O3 -fPIC' log() { level="${1}"; shift From 9159e5a30216f6d721df6a2b383851bf739a35c1 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 11 Nov 2024 01:09:10 +0100 Subject: [PATCH 12/36] external_deps: bump lib versions Co-authored-by: slipher --- external_deps/build.sh | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/external_deps/build.sh b/external_deps/build.sh index 9055ae72dd..41fb852048 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -22,11 +22,11 @@ SDL2_BASEURL='https://www.libsdl.org/release' GLEW_BASEURL='https://github.com/nigels-com/glew/releases' # Index: https://download.sourceforge.net/libpng/files/libpng16 PNG_BASEURL='https://sourceforge.net/projects/libpng/files/libpng16' -# Index: https://downloads.sourceforge.net/project/libjpeg-turbo -JPEG_BASEURL='https://sourceforge.net/projects/libjpeg-turbo/files' +JPEG_BASEURL='https://github.com/libjpeg-turbo/libjpeg-turbo/releases' # Index: https://storage.googleapis.com/downloads.webmproject.org/releases/webp/index.html WEBP_BASEURL='https://storage.googleapis.com/downloads.webmproject.org/releases/webp' -OPENAL_BASEURL='https://openal-soft.org/openal-releases' +# Index: https://github.com/kcat/openal-soft/releases +OPENAL_BASEURL='https://github.com/kcat/openal-soft' OGG_BASEURL='https://downloads.xiph.org/releases/ogg' VORBIS_BASEURL='https://downloads.xiph.org/releases/vorbis' OPUS_BASEURL='https://downloads.xiph.org/releases/opus' @@ -41,24 +41,28 @@ WASMTIME_BASEURL='https://github.com/bytecodealliance/wasmtime/releases' # Package versions PKGCONFIG_VERSION=0.29.2 -NASM_VERSION=2.16.01 -ZLIB_VERSION=1.2.13 -GMP_VERSION=6.2.1 -NETTLE_VERSION=3.8.1 -CURL_VERSION=7.83.1 -SDL2_VERSION=2.26.5 +NASM_VERSION=2.16.03 +ZLIB_VERSION=1.3.1 +GMP_VERSION=6.3.0 +NETTLE_VERSION=3.10.2 +CURL_VERSION=8.15.0 +SDL2_VERSION=2.32.8 GLEW_VERSION=2.2.0 -PNG_VERSION=1.6.39 -JPEG_VERSION=2.1.5.1 -WEBP_VERSION=1.3.2 -OPENAL_VERSION=1.23.1 -OGG_VERSION=1.3.5 +PNG_VERSION=1.6.50 +JPEG_VERSION=3.1.1 +# WebP 1.6.0 introduced AVX2 intrinsics that are not available on +# the GCC 10 compiler provided by Debian Bullseye. +WEBP_VERSION=1.5.0 +# OpenAL 1.24.2 and later requires at least CMake 3.26 but Debian Bullseye +# only provides 3.18 (and even only 3.25 in backports). +OPENAL_VERSION=1.24.1 +OGG_VERSION=1.3.6 VORBIS_VERSION=1.3.7 -OPUS_VERSION=1.4 +OPUS_VERSION=1.5.2 OPUSFILE_VERSION=0.12 NACLSDK_VERSION=44.0.2403.155 NACLRUNTIME_REVISION=2aea5fcfce504862a825920fcaea1a8426afbd6f -NCURSES_VERSION=6.2 +NCURSES_VERSION=6.5 WASISDK_VERSION=16.0 WASMTIME_VERSION=2.0.2 From 7cafe3b3fe429e024bed7d7f3db1705161c41e96 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Wed, 13 Aug 2025 18:00:21 +0200 Subject: [PATCH 13/36] external_deps: bump OpenAL since we're now building on Bookworm with newer CMake --- external_deps/build.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/external_deps/build.sh b/external_deps/build.sh index 41fb852048..075860ef21 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -53,9 +53,7 @@ JPEG_VERSION=3.1.1 # WebP 1.6.0 introduced AVX2 intrinsics that are not available on # the GCC 10 compiler provided by Debian Bullseye. WEBP_VERSION=1.5.0 -# OpenAL 1.24.2 and later requires at least CMake 3.26 but Debian Bullseye -# only provides 3.18 (and even only 3.25 in backports). -OPENAL_VERSION=1.24.1 +OPENAL_VERSION=1.24.3 OGG_VERSION=1.3.6 VORBIS_VERSION=1.3.7 OPUS_VERSION=1.5.2 From 3e7c8ce8cc4a7c5b961a4aaf8b7a414de698484f Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Thu, 14 Aug 2025 17:42:54 +0200 Subject: [PATCH 14/36] external_deps: set forced and optional Opus intrinsics Co-authored-by: slipher --- external_deps/build.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/external_deps/build.sh b/external_deps/build.sh index 075860ef21..3739c5b3a3 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -788,6 +788,18 @@ build_opus() { ;; esac + case "${PLATFORM}" in + *-i686-*|*-amd64-*) + opus_cmake_args+=(-DOPUS_X86_MAY_HAVE_SSE=OFF -DOPUS_X86_PRESUME_SSE=ON) + opus_cmake_args+=(-DOPUS_X86_MAY_HAVE_SSE2=OFF -DOPUS_X86_PRESUME_SSE2=ON) + opus_cmake_args+=(-DOPUS_X86_MAY_HAVE_SSE4_1=OFF -DOPUS_X86_PRESUME_SSE4_1=OFF) + opus_cmake_args+=(-DOPUS_X86_MAY_HAVE_AVX2=OFF -DOPUS_X86_PRESUME_AVX2=OFF) + ;; + *-armhf-*|*-arm64-*) + opus_cmake_args+=(-DOPUS_MAY_HAVE_NEON=OFF -DOPUS_PRESUME_NEON=ON) + ;; + esac + cd "${dir_name}" cmake_build \ From 3719c806e850166f3f84bc3467cda0caf24dc0fa Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Thu, 14 Aug 2025 18:12:01 +0200 Subject: [PATCH 15/36] external_deps: set forced and optional OpenAL intrinsics --- external_deps/build.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/external_deps/build.sh b/external_deps/build.sh index 3739c5b3a3..2b8a4a353a 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -684,6 +684,18 @@ build_openal() { local openal_cmake_args=(-DALSOFT_EXAMPLES=OFF) + case "${PLATFORM}" in + *-i686-*|*-amd64-*) + openal_cmake_args+=(-DALSOFT_CPUEXT_SSE=ON -DALSOFT_REQUIRE_SSE=ON) + openal_cmake_args+=(-DALSOFT_CPUEXT_SSE2=ON -DALSOFT_REQUIRE_SSE2=ON) + openal_cmake_args+=(-DALSOFT_CPUEXT_SSE3=ON -DALSOFT_REQUIRE_SSE3=OFF) + openal_cmake_args+=(-DALSOFT_CPUEXT_SSE4_1=ON -DALSOFT_REQUIRE_SSE4_1=OFF) + ;; + *-armhf-*|*-arm64-*) + openal_cmake_args+=(-DALSOFT_CPUEXT_NEON=ON -DALSOFT_REQUIRE_NEON=ON) + ;; + esac + case "${PLATFORM}" in windows-*-*) cd "${dir_name}" From 680eeac250ac6e21cd4ef3b4e43234c107e1a306 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Thu, 14 Aug 2025 18:33:28 +0200 Subject: [PATCH 16/36] external_deps: set forced JPEG intrinsics --- external_deps/build.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/external_deps/build.sh b/external_deps/build.sh index 2b8a4a353a..e794cce726 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -571,6 +571,8 @@ build_jpeg() { ;; esac + local jpeg_cmake_args=(-DREQUIRE_SIMD=ON) + case "${PLATFORM}" in *-amd64-*) local SYSTEM_PROCESSOR='x86_64' @@ -584,17 +586,17 @@ build_jpeg() { ;; *-arm64-*) local SYSTEM_PROCESSOR='aarch64' + jpeg_cmake_args+=(-DNEON_INTRINSICS=ON) ;; *-armhf-*) local SYSTEM_PROCESSOR='arm' + jpeg_cmake_args+=(-DNEON_INTRINSICS=ON) ;; *) log ERROR 'Unsupported platform for JPEG' ;; esac - local jpeg_cmake_args=() - case "${PLATFORM}" in windows-*-*) ;; From 470fef4b41740291be3087b5c9833819053d9eb4 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Thu, 14 Aug 2025 18:36:53 +0200 Subject: [PATCH 17/36] external_deps: set optional WebP intrinsics --- external_deps/build.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/external_deps/build.sh b/external_deps/build.sh index e794cce726..4146706fdb 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -643,7 +643,8 @@ build_webp() { -DWEBP_BUILD_LIBWEBPMUX=OFF \ -DWEBP_BUILD_VWEBP=OFF \ -DWEBP_BUILD_WEBPINFO=OFF \ - -DWEBP_BUILD_WEBPMUX=OFF + -DWEBP_BUILD_WEBPMUX=OFF \ + -DWEBP_ENABLE_SIMD=ON } # Build OpenAL From 630eee75ce0f9759616df884bd0b91af98c9e8f0 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Thu, 14 Aug 2025 18:38:31 +0200 Subject: [PATCH 18/36] external_deps: disable WebP threads --- external_deps/build.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/external_deps/build.sh b/external_deps/build.sh index 4146706fdb..bff821aa28 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -644,7 +644,8 @@ build_webp() { -DWEBP_BUILD_VWEBP=OFF \ -DWEBP_BUILD_WEBPINFO=OFF \ -DWEBP_BUILD_WEBPMUX=OFF \ - -DWEBP_ENABLE_SIMD=ON + -DWEBP_ENABLE_SIMD=ON \ + -DWEBP_USE_THREAD=OFF } # Build OpenAL From 0790ccaf7e9db0170d4626b619e4a75075f985bf Mon Sep 17 00:00:00 2001 From: slipher Date: Tue, 22 Apr 2025 05:15:46 -0500 Subject: [PATCH 19/36] external_deps: avoid libwinpthread dependency on JPEG dll Also disable the extra "turbo" library. --- external_deps/build.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/external_deps/build.sh b/external_deps/build.sh index bff821aa28..fc147f23b5 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -610,13 +610,19 @@ build_jpeg() { cd "${dir_name}" + # -DHAVE_THREAD_LOCAL=0 overrides the compiler test to avoid the silly thread_local variable, + # which causes a libwinpthread dependency on Windows. cmake_build \ + -DHAVE_THREAD_LOCAL=0 \ -DENABLE_SHARED="${LIBS_SHARED}" \ -DENABLE_STATIC="${LIBS_STATIC}" \ -DCMAKE_SYSTEM_NAME="${SYSTEM_NAME}" \ -DCMAKE_SYSTEM_PROCESSOR="${SYSTEM_PROCESSOR}" \ -DWITH_JPEG8=1 \ + -DWITH_TURBOJPEG=0 \ "${jpeg_cmake_args[@]}" + + rm -r "${PREFIX}/lib/cmake/libjpeg-turbo" } # Build WebP From cce14df958f9d6dc9c141433dfbb3bef53d43d13 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Thu, 14 Aug 2025 18:17:25 +0200 Subject: [PATCH 20/36] external_deps: rework the OpenAL build --- external_deps/build.sh | 43 ++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/external_deps/build.sh b/external_deps/build.sh index fc147f23b5..7b588d1157 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -707,34 +707,37 @@ build_openal() { esac case "${PLATFORM}" in - windows-*-*) - cd "${dir_name}" - cp -r "include/AL" "${PREFIX}/include" - case "${PLATFORM}" in - *-i686-*) - cp "libs/Win32/libOpenAL32.dll.a" "${PREFIX}/lib" - cp "bin/Win32/soft_oal.dll" "${PREFIX}/bin/OpenAL32.dll" - ;; - *-amd64-*) - cp "libs/Win64/libOpenAL32.dll.a" "${PREFIX}/lib" - cp "bin/Win64/soft_oal.dll" "${PREFIX}/bin/OpenAL32.dll" - ;; - esac + windows-i686-*) + local openal_win_dir='Win32' + ;; + windows-amd64-*) + local openal_win_dir='Win64' ;; macos-*-*) - cd "${dir_name}" - - cmake_build \ - -DLIBTYPE=SHARED \ - "${openal_cmake_args[@]}" + openal_cmake_args+=(-DLIBTYPE=SHARED) + ;; + *) + if [ "${LIBS_SHARED}" = 'ON' ] + then + openal_cmake_args+=(-DLIBTYPE=SHARED) + elif [ "${LIBS_STATIC}" = 'ON' ] + then + openal_cmake_args+=(-DLIBTYPE=STATIC) + fi + ;; + esac - install_name_tool -id "@rpath/libopenal.${OPENAL_VERSION}.dylib" "${PREFIX}/lib/libopenal.${OPENAL_VERSION}.dylib" + case "${PLATFORM}" in + windows-*-*) + cd "${dir_name}" + cp -r "include/AL" "${PREFIX}/include" + cp "libs/${openal_win_dir}/libOpenAL32.dll.a" "${PREFIX}/lib" + cp "bin/${openal_win_dir}/soft_oal.dll" "${PREFIX}/bin/OpenAL32.dll" ;; *) cd "${dir_name}" cmake_build \ - -DLIBTYPE=STATIC \ "${openal_cmake_args[@]}" ;; esac From dd7304a859efd024a218b1d13c831c507ae0c3d4 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Thu, 14 Aug 2025 20:55:12 -0500 Subject: [PATCH 21/36] external_deps: bump macOS requirement to 10.14 because of OpenAL --- external_deps/build.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/external_deps/build.sh b/external_deps/build.sh index 7b588d1157..0c525849e2 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -1355,7 +1355,8 @@ setup_windows-amd64-mingw() { # Set up environment for 64-bit amd64 macOS setup_macos-amd64-default() { MACOS_ARCH=x86_64 - export MACOSX_DEPLOYMENT_TARGET=10.12 # works with CMake + # OpenAL requires 10.14. + export MACOSX_DEPLOYMENT_TARGET=10.14 # works with CMake common_setup macos x86_64-apple-darwin11 } From 5b827469fa4595db12099ce7551b243c8f52d098 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Thu, 14 Aug 2025 15:24:47 +0200 Subject: [PATCH 22/36] external_deps: disable Nettle fat, fix build on newer Debian --- external_deps/build.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/external_deps/build.sh b/external_deps/build.sh index 0c525849e2..dcc2c93405 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -367,7 +367,8 @@ build_nettle() { cd "${dir_name}" - configure_build + configure_build \ + --disable-fat } # Build cURL From 8df7e84f8d196cc6421b32cc5616c116013d3546 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Thu, 14 Aug 2025 07:15:38 +0200 Subject: [PATCH 23/36] external_deps: do not install Linux shared libs --- external_deps/build.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/external_deps/build.sh b/external_deps/build.sh index dcc2c93405..0570f7deaa 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -1198,6 +1198,10 @@ build_install() { # Fix import lib paths to use MSVC-style instead of MinGW ones (see 'genlib' target) find "${PKG_PREFIX}/lib/cmake" -name '*.cmake' -execdir sed -i -E 's@[.]dll[.]a\b@.lib@g' {} \; ;; + linux-*-*) + find "${PKG_PREFIX}/lib" -name '*.so' -execdir rm -f -- {} \; + find "${PKG_PREFIX}/lib" -name '*.so.*' -execdir rm -f -- {} \; + ;; esac case "${PLATFORM}" in From 343b68328c21c4d9e322b5dd82e4a1ce60d0f809 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Fri, 15 Aug 2025 02:19:49 +0200 Subject: [PATCH 24/36] external_deps: strip static libraries (required for stripping Nettle debug symbols) --- external_deps/build.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/external_deps/build.sh b/external_deps/build.sh index 0570f7deaa..2e3a27d7f0 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -1201,7 +1201,12 @@ build_install() { linux-*-*) find "${PKG_PREFIX}/lib" -name '*.so' -execdir rm -f -- {} \; find "${PKG_PREFIX}/lib" -name '*.so.*' -execdir rm -f -- {} \; + + local strip="${HOST/-unknown-/-}-strip" + find "${PKG_PREFIX}/lib" -name '*.a' -execdir "${strip}" --strip-unneeded -- {} \; ;; + macos-*-*) + find "${PKG_PREFIX}/lib" -name '*.a' -execdir strip -u {} \; esac case "${PLATFORM}" in From ac2dbd8a526ae861dba0a2066987a785f2b12c15 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Fri, 15 Aug 2025 16:58:02 +0200 Subject: [PATCH 25/36] external_deps: do not install _g symbol libraries (required for cleaning-up Ncurses) --- external_deps/build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/external_deps/build.sh b/external_deps/build.sh index 2e3a27d7f0..4f2d4e698b 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -1201,6 +1201,7 @@ build_install() { linux-*-*) find "${PKG_PREFIX}/lib" -name '*.so' -execdir rm -f -- {} \; find "${PKG_PREFIX}/lib" -name '*.so.*' -execdir rm -f -- {} \; + find "${PKG_PREFIX}/lib" -name '*_g.a' -execdir rm -f -- {} \; local strip="${HOST/-unknown-/-}-strip" find "${PKG_PREFIX}/lib" -name '*.a' -execdir "${strip}" --strip-unneeded -- {} \; From f0cf87f65acf62f9bf4074bb2029b6a021669b06 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Fri, 15 Aug 2025 23:34:07 +0200 Subject: [PATCH 26/36] external_deps: use the same STRIP everytime we need to strip something --- external_deps/build.sh | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/external_deps/build.sh b/external_deps/build.sh index 4f2d4e698b..a914306b49 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -505,8 +505,8 @@ build_glew() { # manually re-add the required flags there. case "${PLATFORM}" in windows-*-*) - env CFLAGS.EXTRA="${CFLAGS}" LDFLAGS.EXTRA="${LDFLAGS}" make SYSTEM="linux-mingw${BITNESS}" GLEW_DEST="${PREFIX}" CC="${CC}" AR="${AR}" RANLIB="${RANLIB}" STRIP="${HOST}-strip" LD="${LD}" - env CFLAGS.EXTRA="${CFLAGS}" LDFLAGS.EXTRA="${LDFLAGS}" make install SYSTEM="linux-mingw${BITNESS}" GLEW_DEST="${PREFIX}" CC="${CC}" AR="${AR}" RANLIB="${RANLIB}" STRIP="${HOST}-strip" LD="${LD}" + env CFLAGS.EXTRA="${CFLAGS}" LDFLAGS.EXTRA="${LDFLAGS}" make SYSTEM="linux-mingw${BITNESS}" GLEW_DEST="${PREFIX}" CC="${CC}" AR="${AR}" RANLIB="${RANLIB}" STRIP="${STRIP}" LD="${LD}" + env CFLAGS.EXTRA="${CFLAGS}" LDFLAGS.EXTRA="${LDFLAGS}" make install SYSTEM="linux-mingw${BITNESS}" GLEW_DEST="${PREFIX}" CC="${CC}" AR="${AR}" RANLIB="${RANLIB}" STRIP="${STRIP}" LD="${LD}" mv "${PREFIX}/lib/glew32.dll" "${PREFIX}/bin/" rm "${PREFIX}/lib/libglew32.a" cp lib/libglew32.dll.a "${PREFIX}/lib/" @@ -517,8 +517,7 @@ build_glew() { install_name_tool -id "@rpath/libGLEW.${GLEW_VERSION}.dylib" "${PREFIX}/lib/libGLEW.${GLEW_VERSION}.dylib" ;; linux-*-*) - local strip="${HOST/-unknown-/-}-strip" - env CFLAGS.EXTRA="${CFLAGS}" LDFLAGS.EXTRA="${LDFLAGS}" make GLEW_DEST="${PREFIX}" CC="${CC}" LD="${CC}" STRIP="${strip}" + env CFLAGS.EXTRA="${CFLAGS}" LDFLAGS.EXTRA="${LDFLAGS}" make GLEW_DEST="${PREFIX}" CC="${CC}" LD="${CC}" STRIP="${STRIP}" env CFLAGS.EXTRA="${CFLAGS}" LDFLAGS.EXTRA="${LDFLAGS}" make install GLEW_DEST="${PREFIX}" CC="${CC}" LD="${CC}" LIBDIR="${PREFIX}/lib" ;; *) @@ -867,9 +866,8 @@ build_ncurses() { # Brutally disable writing to database cp /dev/null misc/run_tic.in # Configure terminfo search dirs based on the ones used in Debian. By default it will only look in (only) the install directory. - local strip="${HOST/-unknown-/-}-strip" configure_build \ - --with-strip-program="${strip}" \ + --with-strip-program="${STRIP}" \ --without-progs \ --enable-widec \ --with-terminfo-dirs=/etc/terminfo:/lib/terminfo \ @@ -1187,11 +1185,11 @@ build_install() { # Strip libraries case "${PLATFORM}" in windows-*-mingw) - find "${PKG_PREFIX}/bin" -name '*.dll' -execdir "${HOST}-strip" --strip-unneeded -- {} \; - find "${PKG_PREFIX}/lib" -name '*.a' -execdir "${HOST}-strip" --strip-unneeded -- {} \; + find "${PKG_PREFIX}/bin" -name '*.dll' -execdir "${STRIP}" --strip-unneeded -- {} \; + find "${PKG_PREFIX}/lib" -name '*.a' -execdir "${STRIP}" --strip-unneeded -- {} \; ;; windows-*-msvc) - find "${PKG_PREFIX}/bin" -name '*.dll' -execdir "${HOST}-strip" --strip-unneeded -- {} \; + find "${PKG_PREFIX}/bin" -name '*.dll' -execdir "${STRIP}" --strip-unneeded -- {} \; find "${PKG_PREFIX}/lib" -name '*.a' -execdir rm -f -- {} \; find "${PKG_PREFIX}/lib" -name '*.exp' -execdir rm -f -- {} \; @@ -1203,11 +1201,10 @@ build_install() { find "${PKG_PREFIX}/lib" -name '*.so.*' -execdir rm -f -- {} \; find "${PKG_PREFIX}/lib" -name '*_g.a' -execdir rm -f -- {} \; - local strip="${HOST/-unknown-/-}-strip" - find "${PKG_PREFIX}/lib" -name '*.a' -execdir "${strip}" --strip-unneeded -- {} \; + find "${PKG_PREFIX}/lib" -name '*.a' -execdir "${STRIP}" --strip-unneeded -- {} \; ;; macos-*-*) - find "${PKG_PREFIX}/lib" -name '*.a' -execdir strip -u {} \; + find "${PKG_PREFIX}/lib" -name '*.a' -execdir "${STRIP}" -u {} \; esac case "${PLATFORM}" in @@ -1263,7 +1260,7 @@ common_setup() { mkdir -p "${PREFIX}/include" mkdir -p "${PREFIX}/lib" - export CC CXX LD AR RANLIB PKG_CONFIG PKG_CONFIG_PATH PATH CFLAGS CXXFLAGS CPPFLAGS LDFLAGS + export CC CXX LD AR RANLIB STRIP PKG_CONFIG PKG_CONFIG_PATH PATH CFLAGS CXXFLAGS CPPFLAGS LDFLAGS } common_setup_arch() { @@ -1299,6 +1296,7 @@ common_setup_arch() { # the Windows build of Lua is only used in developer gamelogic builds, and Microsoft # supports %lld since Visual Studio 2013. Also we don't build Lua anymore. common_setup_windows() { + STRIP="${HOST}-strip" LD="${HOST}-ld" AR="${HOST}-ar" RANLIB="${HOST}-ranlib" @@ -1324,6 +1322,7 @@ common_setup_mingw() { common_setup_macos() { CC='clang' CXX='clang++' + STRIP='strip' CFLAGS+=" -arch ${MACOS_ARCH}" CXXFLAGS+=" -arch ${MACOS_ARCH}" LDFLAGS+=" -arch ${MACOS_ARCH}" @@ -1333,6 +1332,7 @@ common_setup_macos() { common_setup_linux() { CC="${HOST/-unknown-/-}-gcc" CXX="${HOST/-unknown-/-}-g++" + STRIP="${HOST/-unknown-/-}-strip" CFLAGS+=' -fPIC' CXXFLAGS+=' -fPIC' } From 1665cd6e6b0c50bb63039073e96018adf51d03f4 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Fri, 15 Aug 2025 23:39:15 +0200 Subject: [PATCH 27/36] external_deps: refactor the GLEW build --- external_deps/build.sh | 43 +++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/external_deps/build.sh b/external_deps/build.sh index a914306b49..30501d389e 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -497,32 +497,53 @@ build_glew() { cd "${dir_name}" + local glew_env=(LDFLAGS.EXTRA="${LDFLAGS}") + local glew_options=(GLEW_DEST="${PREFIX}" CC="${CC}" AR="${AR}" STRIP="${STRIP}") + + case "${PLATFORM}" in + windows-*-*) + glew_env+=(CFLAGS.EXTRA="${CFLAGS}") + glew_options+=(SYSTEM="linux-mingw${BITNESS}" LD="${LD}" AR="${AR}" RANLIB="${RANLIB}") + ;; + macos-*-*) + glew_env+=(CFLAGS.EXTRA="${CFLAGS} -dynamic -fno-common") + glew_options+=(SYSTEM=darwin LD="${CC}") + ;; + linux-*-*) + glew_env+=(CFLAGS.EXTRA="${CFLAGS}") + glew_options+=(LIBDIR="${PREFIX}/lib" LD="${CC}") + ;; + *) + log ERROR 'Unsupported platform for GLEW' + ;; + esac + # env hack: CFLAGS.EXTRA is populated with some flags, which are sometimess necessary for # compilation, in the makefile with +=. If CFLAGS.EXTRA is set on the command line, those # += will be ignored. But if it is set via the environment, the two sources are actually # concatenated how we would like. Bash doesn't allow variables with a dot so use env. # The hack doesn't work on Mac's ancient Make (the env var has no effect), so we have to # manually re-add the required flags there. + case "${PLATFORM}" in + macos-*-*) + make "${glew_env[@]}" "${glew_options[@]}" + make install "${glew_env[@]}" "${glew_options[@]}" + ;; + *) + env "${glew_env[@]}" make "${glew_options[@]}" + env "${glew_env[@]}" make install "${glew_options[@]}" + ;; + esac + case "${PLATFORM}" in windows-*-*) - env CFLAGS.EXTRA="${CFLAGS}" LDFLAGS.EXTRA="${LDFLAGS}" make SYSTEM="linux-mingw${BITNESS}" GLEW_DEST="${PREFIX}" CC="${CC}" AR="${AR}" RANLIB="${RANLIB}" STRIP="${STRIP}" LD="${LD}" - env CFLAGS.EXTRA="${CFLAGS}" LDFLAGS.EXTRA="${LDFLAGS}" make install SYSTEM="linux-mingw${BITNESS}" GLEW_DEST="${PREFIX}" CC="${CC}" AR="${AR}" RANLIB="${RANLIB}" STRIP="${STRIP}" LD="${LD}" mv "${PREFIX}/lib/glew32.dll" "${PREFIX}/bin/" rm "${PREFIX}/lib/libglew32.a" cp lib/libglew32.dll.a "${PREFIX}/lib/" ;; macos-*-*) - make SYSTEM=darwin GLEW_DEST="${PREFIX}" CC="${CC}" LD="${CC}" CFLAGS.EXTRA="${CFLAGS} -dynamic -fno-common" LDFLAGS.EXTRA="${LDFLAGS}" - make install SYSTEM=darwin GLEW_DEST="${PREFIX}" CC="${CC}" LD="${CC}" CFLAGS.EXTRA="${CFLAGS} -dynamic -fno-common" LDFLAGS.EXTRA="${LDFLAGS}" install_name_tool -id "@rpath/libGLEW.${GLEW_VERSION}.dylib" "${PREFIX}/lib/libGLEW.${GLEW_VERSION}.dylib" ;; - linux-*-*) - env CFLAGS.EXTRA="${CFLAGS}" LDFLAGS.EXTRA="${LDFLAGS}" make GLEW_DEST="${PREFIX}" CC="${CC}" LD="${CC}" STRIP="${STRIP}" - env CFLAGS.EXTRA="${CFLAGS}" LDFLAGS.EXTRA="${LDFLAGS}" make install GLEW_DEST="${PREFIX}" CC="${CC}" LD="${CC}" LIBDIR="${PREFIX}/lib" - ;; - *) - log ERROR 'Unsupported platform for GLEW' - ;; esac } From 272fe0a5854693666c0b583158e969c8321c5180 Mon Sep 17 00:00:00 2001 From: slipher Date: Fri, 15 Aug 2025 15:42:13 -0500 Subject: [PATCH 28/36] external_deps: check for absolute paths in result --- external_deps/build.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/external_deps/build.sh b/external_deps/build.sh index 30501d389e..201b3d26b5 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -1237,6 +1237,21 @@ build_install() { # Remove empty directories find "${PKG_PREFIX}/" -mindepth 1 -type d -empty -delete + + # Check for unwanted embedded paths with a couple of exemptions: + # - Opus's release mode assertions - https://github.com/xiph/opus/issues/399 + # - SDL3 has a small number of renderer backend filenames embedded for some reason + local good=true + for f in $(find "${PKG_PREFIX}" -type f -not -name '*libopus*' -not -name 'libSDL3.a'); do + if grep --with-filename external_deps "${f}" + then + good=false + elif [[ $? != 1 ]] + then + exit $? # grep errored + fi + done + "${good}" || log ERROR 'Absolute paths found embedded in install. This may be due to builds with debug symbols or config files that need to be fixed.' } # Create a redistributable package for the dependencies From 2c4c5b26c7d02d5c4c8a14a6bb46191d818f7173 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Wed, 3 Sep 2025 18:14:18 +0200 Subject: [PATCH 29/36] external_deps: make pkg-config working when cross-compiling Without setting PKG_CONFIG_PATH to the cross database, pkg-config will only report libraries installed for the native target, not for the cross target. SDL3 relies on pkg-config to enable Wayland support, so we need that to enable Wayland support when cross-compiling SDL3 when the related libraries are only installed for the cross target. --- external_deps/build.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/external_deps/build.sh b/external_deps/build.sh index 201b3d26b5..ea78504ad3 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -72,6 +72,8 @@ CXX='false' LD='ld' AR='ar' RANLIB='ranlib' +PKG_CONFIG='pkg-config' +CROSS_PKG_CONFIG_PATH='' LIBS_SHARED='OFF' LIBS_STATIC='ON' CMAKE_TOOLCHAIN='' @@ -1286,8 +1288,7 @@ common_setup() { BUILD_DIR="${WORK_DIR}/${BUILD_BASEDIR}" PREFIX="${BUILD_DIR}/prefix" PATH="${PREFIX}/bin:${PATH}" - PKG_CONFIG="pkg-config" - PKG_CONFIG_PATH="${PREFIX}/lib/pkgconfig" + PKG_CONFIG_PATH="${PREFIX}/lib/pkgconfig:${CROSS_PKG_CONFIG_PATH}" CPPFLAGS+=" -I${PREFIX}/include" LDFLAGS+=" -L${PREFIX}/lib" @@ -1369,6 +1370,7 @@ common_setup_linux() { CC="${HOST/-unknown-/-}-gcc" CXX="${HOST/-unknown-/-}-g++" STRIP="${HOST/-unknown-/-}-strip" + CROSS_PKG_CONFIG_PATH="/usr/lib/${HOST/-unknown-/-}/pkgconfig" CFLAGS+=' -fPIC' CXXFLAGS+=' -fPIC' } From 0c831a23ae93ee0ce4b7ea42a5e874abda0f4874 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Thu, 4 Sep 2025 01:28:32 +0200 Subject: [PATCH 30/36] external_deps: disable -fpic when building nettle, we already use -fPIC This avoids this error when linking the linux-arm64 engine: libnettle.a(buffer-init.o): in function `nettle_buffer_init': (.text+0x8): relocation truncated to fit: R_AARCH64_LD64_GOTPAGE_LO15 against symbol `nettle_realloc' defined in .text section in libnettle.a(realloc.o) /usr/aarch64-linux-gnu/bin/ld: (.text+0x8): warning: too many GOT entries for -fpic, please recompile with -fPIC --- external_deps/build.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/external_deps/build.sh b/external_deps/build.sh index ea78504ad3..04a117d874 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -370,7 +370,8 @@ build_nettle() { cd "${dir_name}" configure_build \ - --disable-fat + --disable-fat \ + --disable-pic } # Build cURL From 7bde7ceba02c37ed28a7fe1e704330bf101ef74d Mon Sep 17 00:00:00 2001 From: slipher Date: Thu, 14 Aug 2025 13:33:41 -0500 Subject: [PATCH 31/36] dl_main: CURL_STATICLIB is now injected by CURLTargets.cmake --- src/engine/client/dl_main.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/engine/client/dl_main.cpp b/src/engine/client/dl_main.cpp index d7775dea87..0044c64794 100644 --- a/src/engine/client/dl_main.cpp +++ b/src/engine/client/dl_main.cpp @@ -39,9 +39,6 @@ Maryland 20850 USA. #include "common/Common.h" -#ifdef __MINGW32__ -#define CURL_STATICLIB -#endif #include #include "common/FileSystem.h" From c5214f90af8ea9e508d2c456f47e34cc52126a66 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Wed, 13 Aug 2025 16:15:17 +0300 Subject: [PATCH 32/36] Switch to SDL3, bump deps version CMakeLists.txt - Reaper - illwieckz - slipher azure-pipelines.yml - Reaper external_deps/build.sh - illwieckz - slipher src/engine/client/ClientApplication.cpp src/engine/client/cl_main.cpp src/engine/client/key_identification.cpp src/engine/framework/System.cpp src/engine/sys/sdl_input.cpp - Reaper - slipher (joystick init, fixes) src/engine/sys/sdl_glimp.cpp - illwieckz - slipher (taskbar icon, fixes) Co-authored-by: Thomas Debesse Co-authored-by: slipher --- .github/workflows/codeql.yml | 2 +- CMakeLists.txt | 28 +-- azure-pipelines.yml | 2 +- cmake/FindOldSDL2.cmake | 186 ---------------- external_deps/build.sh | 80 +++---- src/engine/client/ClientApplication.cpp | 10 +- src/engine/client/cl_main.cpp | 2 +- src/engine/client/key_identification.cpp | 8 +- src/engine/framework/System.cpp | 3 +- src/engine/sys/sdl_glimp.cpp | 220 ++++++++++++------- src/engine/sys/sdl_input.cpp | 258 ++++++++++++----------- 11 files changed, 331 insertions(+), 468 deletions(-) delete mode 100644 cmake/FindOldSDL2.cmake diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 55340c30c7..23bd0b2562 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -73,7 +73,7 @@ jobs: run: | set -x sudo apt-get update - sudo apt-get -y -q --no-install-recommends install zlib1g-dev libncursesw5-dev libgeoip-dev nettle-dev libgmp-dev libcurl4-gnutls-dev libsdl2-dev libogg-dev libvorbis-dev libopusfile-dev libwebp-dev libjpeg8-dev libpng-dev libfreetype6-dev libglew-dev libopenal-dev ninja-build + sudo apt-get -y -q --no-install-recommends install zlib1g-dev libncursesw5-dev libgeoip-dev nettle-dev libgmp-dev libcurl4-gnutls-dev libogg-dev libvorbis-dev libopusfile-dev libwebp-dev libjpeg8-dev libpng-dev libfreetype6-dev libglew-dev libopenal-dev ninja-build git submodule update --init --recursive curl -sS https://gitlab.com/illwieckz/git-checkout-modules/raw/master/git-checkout-modules -o ~/git-checkout-modules diff --git a/CMakeLists.txt b/CMakeLists.txt index f2ef9c2f6a..29dde26819 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -214,7 +214,7 @@ else() endif() # Dependencies version, this must match the number in external_deps/build.sh -set(DEPS_VERSION 10) +set(DEPS_VERSION 11) option(USE_EXTERNAL_DEPS "Download or reuse dependencies from EXTERNAL_DEPS_DIR (mandatory for building and running NaCl .nexe binaries)." ON) @@ -725,30 +725,12 @@ endif() # SDL, required for all targets on win32 because of iconv and SDL_SetHint(SDL_TIMER_RESOLUTION, 0) if (BUILD_CLIENT OR WIN32) - find_package(SDL2 CONFIG) - - if (SDL2_SDL2main_FOUND) - mark_as_advanced(SDL2_DIR) - else() - # We cannot use REQUIRED because it would look - # for OldSDL2_FOUND instead of SDL2_FOUND. - find_package(OldSDL2) - - if (NOT SDL2_FOUND) - message(FATAL_ERROR "Could NOT find SDL2") - endif() - - include_directories(${SDL2_INCLUDE_DIR}) - - mark_as_advanced(SDL2MAIN_LIBRARY SDL2_LIBRARY SDL2_INCLUDE_DIR) - endif () + find_package(SDL3 REQUIRED CONFIG) if (WIN32) - set(LIBS_ENGINE_BASE ${LIBS_ENGINE_BASE} - $<$:SDL2::SDL2main> SDL2::SDL2) + set(LIBS_ENGINE_BASE ${LIBS_ENGINE_BASE} SDL3::SDL3) else() - set(LIBS_CLIENT ${LIBS_CLIENT} - $<$:SDL2::SDL2main> SDL2::SDL2) + set(LIBS_CLIENT ${LIBS_CLIENT} SDL3::SDL3) endif() endif() @@ -1100,7 +1082,7 @@ if (DEPS_DIR AND (BUILD_CLIENT OR BUILD_TTY_CLIENT OR BUILD_SERVER OR BUILD_DUMM # Windows requires some libraries from external_deps if (WIN32) - file(GLOB RUNTIME_LIBS ${DEPS_DIR}/bin/*.dll ${DEPS_DIR}/SDL2/lib/*/SDL2.dll) + file(GLOB RUNTIME_LIBS ${DEPS_DIR}/bin/*.dll ${DEPS_DIR}/SDL3/lib/*/SDL3.dll) foreach(RUNTIME_LIB ${RUNTIME_LIBS}) add_custom_command(TARGET runtime_deps PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 9152a3adf8..5db00f050f 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -120,7 +120,7 @@ jobs: - bash: | set -e sudo apt-get update - sudo apt-get -y -q --no-install-recommends install zlib1g-dev libncursesw5-dev libgeoip-dev nettle-dev libgmp-dev libcurl4-gnutls-dev libsdl2-dev libogg-dev libvorbis-dev libopusfile-dev libwebp-dev libjpeg8-dev libpng-dev libfreetype6-dev libglew-dev libopenal-dev liblua5.2-dev ninja-build $(EXTRA_PACKAGES) + sudo apt-get -y -q --no-install-recommends install zlib1g-dev libncursesw5-dev libgeoip-dev nettle-dev libgmp-dev libcurl4-gnutls-dev libogg-dev libvorbis-dev libopusfile-dev libwebp-dev libjpeg8-dev libpng-dev libfreetype6-dev libglew-dev libopenal-dev liblua5.2-dev ninja-build $(EXTRA_PACKAGES) $(EXTRA_INSTALLS) displayName: 'Install deps' - bash: | diff --git a/cmake/FindOldSDL2.cmake b/cmake/FindOldSDL2.cmake deleted file mode 100644 index 7c7a665ba9..0000000000 --- a/cmake/FindOldSDL2.cmake +++ /dev/null @@ -1,186 +0,0 @@ -# Locate SDL2 library -# This module defines -# SDL2_LIBRARY, the name of the library to link against -# SDL2_FOUND, if false, do not try to link to SDL2 -# SDL2_INCLUDE_DIR, where to find SDL.h -# -# This module responds to the the flag: -# SDL2_BUILDING_LIBRARY -# If this is defined, then no SDL2_main will be linked in because -# only applications need main(). -# Otherwise, it is assumed you are building an application and this -# module will attempt to locate and set the the proper link flags -# as part of the returned SDL2_LIBRARY variable. -# -# Don't forget to include SDL2main.h and SDL2main.m your project for the -# OS X framework based version. (Other versions link to -lSDL2main which -# this module will try to find on your behalf.) Also for OS X, this -# module will automatically add the -framework Cocoa on your behalf. -# -# -# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration -# and no SDL2_LIBRARY, it means CMake did not find your SDL2 library -# (SDL2.dll, libsdl2.so, SDL2.framework, etc). -# Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again. -# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value -# as appropriate. These values are used to generate the final SDL2_LIBRARY -# variable, but when these values are unset, SDL2_LIBRARY does not get created. -# -# -# $SDL2DIR is an environment variable that would -# correspond to the ./configure --prefix=$SDL2DIR -# used in building SDL2. -# l.e.galup 9-20-02 -# -# Modified by Eric Wing. -# Added code to assist with automated building by using environmental variables -# and providing a more controlled/consistent search behavior. -# Added new modifications to recognize OS X frameworks and -# additional Unix paths (FreeBSD, etc). -# Also corrected the header search path to follow "proper" SDL2 guidelines. -# Added a search for SDL2main which is needed by some platforms. -# Added a search for threads which is needed by some platforms. -# Added needed compile switches for MinGW. -# -# On OSX, this will prefer the Framework version (if found) over others. -# People will have to manually change the cache values of -# SDL2_LIBRARY to override this selection or set the CMake environment -# CMAKE_INCLUDE_PATH to modify the search paths. -# -# Note that the header path has changed from SDL2/SDL.h to just SDL.h -# This needed to change because "proper" SDL2 convention -# is #include "SDL.h", not . This is done for portability -# reasons because not all systems place things in SDL2/ (see FreeBSD). -# -# Ported by Johnny Patterson. This is a literal port for SDL2 of the FindSDL.cmake -# module with the minor edit of changing "SDL" to "SDL2" where necessary. This -# was not created for redistribution, and exists temporarily pending official -# SDL2 CMake modules. - -#============================================================================= -# Copyright 2003-2009 Kitware, Inc. -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distribute this file outside of CMake, substitute the full -# License text for the above reference.) - -FIND_PATH(SDL2_INCLUDE_DIR SDL.h - HINTS - $ENV{SDL2DIR} - PATH_SUFFIXES include/SDL2 include - PATHS - ~/Library/Frameworks - /Library/Frameworks - /usr/local/include/SDL2 - /usr/include/SDL2 - /sw # Fink - /opt/local # DarwinPorts - /opt/csw # Blastwave - /opt -) -#MESSAGE("SDL2_INCLUDE_DIR is ${SDL2_INCLUDE_DIR}") - -FIND_LIBRARY(SDL2_LIBRARY_TEMP - NAMES SDL2 - HINTS - $ENV{SDL2DIR} - PATH_SUFFIXES lib64 lib - PATHS - /sw - /opt/local - /opt/csw - /opt -) - -#MESSAGE("SDL2_LIBRARY_TEMP is ${SDL2_LIBRARY_TEMP}") - -IF(NOT SDL2_BUILDING_LIBRARY) - IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") - # Non-OS X framework versions expect you to also dynamically link to - # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms - # seem to provide SDL2main for compatibility even though they don't - # necessarily need it. - FIND_LIBRARY(SDL2MAIN_LIBRARY - NAMES SDL2main - HINTS - $ENV{SDL2DIR} - PATH_SUFFIXES lib64 lib - PATHS - /sw - /opt/local - /opt/csw - /opt - ) - ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") -ENDIF(NOT SDL2_BUILDING_LIBRARY) - -# SDL2 may require threads on your system. -# The Apple build may not need an explicit flag because one of the -# frameworks may already provide it. -# But for non-OSX systems, I will use the CMake Threads package. -IF(NOT APPLE) - FIND_PACKAGE(Threads) -ENDIF(NOT APPLE) - -# MinGW needs an additional library, mwindows -# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows -# (Actually on second look, I think it only needs one of the m* libraries.) -IF(MINGW) - SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW") -ENDIF(MINGW) - -SET(SDL2_FOUND "NO") -IF(SDL2_LIBRARY_TEMP) - # For SDL2main - IF(NOT SDL2_BUILDING_LIBRARY) - IF(SDL2MAIN_LIBRARY) - SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP}) - ENDIF(SDL2MAIN_LIBRARY) - ENDIF(NOT SDL2_BUILDING_LIBRARY) - - # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. - # CMake doesn't display the -framework Cocoa string in the UI even - # though it actually is there if I modify a pre-used variable. - # I think it has something to do with the CACHE STRING. - # So I use a temporary variable until the end so I can set the - # "real" variable in one-shot. - IF(APPLE) - SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa") - ENDIF(APPLE) - - # For threads, as mentioned Apple doesn't need this. - # In fact, there seems to be a problem if I used the Threads package - # and try using this line, so I'm just skipping it entirely for OS X. - IF(NOT APPLE) - SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT}) - ENDIF(NOT APPLE) - - # For MinGW library - IF(MINGW) - SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP}) - ENDIF(MINGW) - - # Set the final string here so the GUI reflects the final state. - SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found") - # Set the temp variable to INTERNAL so it is not seen in the CMake GUI - SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "") - - SET(SDL2_FOUND "YES") -ENDIF(SDL2_LIBRARY_TEMP) - -INCLUDE(FindPackageHandleStandardArgs) - -FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 - REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) - -if(SDL2_FOUND AND NOT TARGET SDL2::SDL2) - add_library(SDL2::SDL2 INTERFACE IMPORTED) - set_property(TARGET SDL2::SDL2 PROPERTY INTERFACE_LINK_LIBRARIES "${SDL2_LIBRARIES}") - set_property(TARGET SDL2::SDL2 PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIRS}") -endif() diff --git a/external_deps/build.sh b/external_deps/build.sh index 04a117d874..6e53b868d3 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -9,7 +9,7 @@ WORK_DIR="${PWD}" # This should match the DEPS_VERSION in CMakeLists.txt. # This is mostly to ensure the path the files end up at if you build deps yourself # are the same as the ones when extracting from the downloaded packages. -DEPS_VERSION=10 +DEPS_VERSION=11 # Package download pages PKGCONFIG_BASEURL='https://pkg-config.freedesktop.org/releases' @@ -18,7 +18,7 @@ ZLIB_BASEURL='https://zlib.net/fossils' GMP_BASEURL='https://gmplib.org/download/gmp' NETTLE_BASEURL='https://mirror.cyberbits.eu/gnu/nettle' CURL_BASEURL='https://curl.se/download' -SDL2_BASEURL='https://www.libsdl.org/release' +SDL3_BASEURL='https://www.libsdl.org/release' GLEW_BASEURL='https://github.com/nigels-com/glew/releases' # Index: https://download.sourceforge.net/libpng/files/libpng16 PNG_BASEURL='https://sourceforge.net/projects/libpng/files/libpng16' @@ -46,7 +46,7 @@ ZLIB_VERSION=1.3.1 GMP_VERSION=6.3.0 NETTLE_VERSION=3.10.2 CURL_VERSION=8.15.0 -SDL2_VERSION=2.32.8 +SDL3_VERSION=3.2.22 GLEW_VERSION=2.2.0 PNG_VERSION=1.6.50 JPEG_VERSION=3.1.1 @@ -243,8 +243,8 @@ cmake_build() { cmake --install build --strip } -# Build pkg-config -# Still needed, at least on macos, for opusfile +# Build pkg-config, needed for opusfile and SDL3. +# As a host-mode dependency it must be provided by the system when cross-compiling. build_pkgconfig() { local dir_name="pkg-config-${PKGCONFIG_VERSION}" local archive_name="${dir_name}.tar.gz" @@ -416,28 +416,28 @@ build_curl() { -DHTTP_ONLY=ON # Implies all CURL_DISABLE_xxx options except HTTP } -# Build SDL2 -build_sdl2() { - local dir_name="SDL2-${SDL2_VERSION}" +# Build SDL3 +build_sdl3() { + local dir_name="SDL3-${SDL3_VERSION}" case "${PLATFORM}" in windows-*-mingw) - local archive_name="SDL2-devel-${SDL2_VERSION}-mingw.tar.gz" + local archive_name="SDL3-devel-${SDL3_VERSION}-mingw.tar.gz" ;; windows-*-msvc) - local archive_name="SDL2-devel-${SDL2_VERSION}-VC.zip" + local archive_name="SDL3-devel-${SDL3_VERSION}-VC.zip" ;; macos-*-*) - local archive_name="SDL2-${SDL2_VERSION}.dmg" + local archive_name="SDL3-${SDL3_VERSION}.dmg" ;; *) - local archive_name="SDL2-${SDL2_VERSION}.tar.gz" + local archive_name="SDL3-${SDL3_VERSION}.tar.gz" ;; esac - download_extract sdl2 "${archive_name}" \ - "${SDL2_BASEURL}/${archive_name}" \ - "https://github.com/libsdl-org/SDL/releases/download/release-${SDL2_VERSION}/${archive_name}" + download_extract sdl3 "${archive_name}" \ + "${SDL3_BASEURL}/${archive_name}" \ + "https://github.com/libsdl-org/SDL/releases/download/release-${SDL3_VERSION}/${archive_name}" "${download_only}" && return @@ -445,40 +445,42 @@ build_sdl2() { windows-*-mingw) cd "${dir_name}" cp -rv "${HOST}"/* "${PREFIX}/" + rm "${PREFIX}/lib/libSDL3_test.a" + rm "${PREFIX}/lib/cmake/SDL3/SDL3testTargets"*.cmake ;; windows-*-msvc) cd "${dir_name}" - mkdir -p "${PREFIX}/SDL2/cmake" - cp "cmake/"* "${PREFIX}/SDL2/cmake" - mkdir -p "${PREFIX}/SDL2/include" - cp "include/"* "${PREFIX}/SDL2/include" + mkdir -p "${PREFIX}/SDL3/cmake" + cp "cmake/"* "${PREFIX}/SDL3/cmake" + mkdir -p "${PREFIX}/SDL3/include/SDL3" + cp "include/SDL3/"* "${PREFIX}/SDL3/include/SDL3" case "${PLATFORM}" in *-i686-*) - local sdl2_lib_dir='lib/x86' + local sdl3_lib_dir='lib/x86' ;; *-amd64-*) - local sdl2_lib_dir='lib/x64' + local sdl3_lib_dir='lib/x64' ;; *) - log ERROR 'Unsupported platform for SDL2' + log ERROR 'Unsupported platform for SDL3' ;; esac - mkdir -p "${PREFIX}/SDL2/${sdl2_lib_dir}" - cp "${sdl2_lib_dir}/"{SDL2.lib,SDL2main.lib} "${PREFIX}/SDL2/${sdl2_lib_dir}" - cp "${sdl2_lib_dir}/"*.dll "${PREFIX}/SDL2/${sdl2_lib_dir}" + mkdir -p "${PREFIX}/SDL3/${sdl3_lib_dir}" + cp "${sdl3_lib_dir}/SDL3.lib" "${PREFIX}/SDL3/${sdl3_lib_dir}" + cp "${sdl3_lib_dir}/"*.dll "${PREFIX}/SDL3/${sdl3_lib_dir}" ;; macos-*-*) - rm -rf "${PREFIX}/lib/SDL2.framework" - cp -R "SDL2.framework" "${PREFIX}/lib" + cp -R "SDL3.xcframework/macos-arm64_x86_64/SDL3.framework" "${PREFIX}/lib" ;; *) cd "${dir_name}" - cmake_build + cmake_build \ + -DSDL_TEST_LIBRARY=OFF - # Workaround for an SDL2 CMake bug, we need to provide + # Workaround for an SDL CMake bug, we need to provide # a bin/ directory even when nothing is used from it. mkdir -p "${PREFIX}/bin" # We don't keep empty folders. @@ -1233,8 +1235,8 @@ build_install() { case "${PLATFORM}" in windows-*-*) - # CMake looks for libSDL2.a and aborts if missing if this file exists: - rm -rf "${PKG_PREFIX}/lib/cmake/SDL2/SDL2staticTargets.cmake" + # CMake looks for libSDL3.a and aborts if missing if this file exists: + rm -rf "${PKG_PREFIX}/lib/cmake/SDL3/SDL3staticTargets.cmake" ;; esac @@ -1430,29 +1432,29 @@ setup_linux-arm64-default() { common_setup linux aarch64-unknown-linux-gnu } -base_windows_amd64_msvc_packages='zlib gmp nettle curl sdl2 glew png jpeg webp openal ogg vorbis opus opusfile naclsdk depcheck genlib' +base_windows_amd64_msvc_packages='zlib gmp nettle curl sdl3 glew png jpeg webp openal ogg vorbis opus opusfile naclsdk depcheck genlib' all_windows_amd64_msvc_packages="${base_windows_amd64_msvc_packages}" base_windows_i686_msvc_packages="${base_windows_amd64_msvc_packages}" all_windows_i686_msvc_packages="${base_windows_amd64_msvc_packages}" -base_windows_amd64_mingw_packages='zlib gmp nettle curl sdl2 glew png jpeg webp openal ogg vorbis opus opusfile naclsdk depcheck' +base_windows_amd64_mingw_packages='zlib gmp nettle curl sdl3 glew png jpeg webp openal ogg vorbis opus opusfile naclsdk depcheck' all_windows_amd64_mingw_packages="${base_windows_amd64_mingw_packages}" base_windows_i686_mingw_packages="${base_windows_amd64_mingw_packages}" all_windows_i686_mingw_packages="${base_windows_amd64_mingw_packages}" -base_macos_amd64_default_packages='pkgconfig nasm gmp nettle sdl2 glew png jpeg webp openal ogg vorbis opus opusfile naclsdk' +base_macos_amd64_default_packages='pkgconfig nasm gmp nettle sdl3 glew png jpeg webp openal ogg vorbis opus opusfile naclsdk' all_macos_amd64_default_packages="${base_macos_amd64_default_packages}" -base_linux_i686_default_packages='naclsdk' -all_linux_i686_default_packages='zlib gmp nettle curl sdl2 glew png jpeg webp openal ogg vorbis opus opusfile ncurses naclsdk' +base_linux_i686_default_packages='sdl3 naclsdk' +all_linux_i686_default_packages='zlib gmp nettle curl sdl3 glew png jpeg webp openal ogg vorbis opus opusfile ncurses naclsdk' base_linux_amd64_default_packages="${base_linux_i686_default_packages} naclruntime" all_linux_amd64_default_packages="${all_linux_i686_default_packages} naclruntime" -base_linux_arm64_default_packages='naclsdk' -all_linux_arm64_default_packages='zlib gmp nettle curl sdl2 glew png jpeg webp openal ogg vorbis opus opusfile ncurses naclsdk' +base_linux_arm64_default_packages='sdl3 naclsdk' +all_linux_arm64_default_packages='zlib gmp nettle curl sdl3 glew png jpeg webp openal ogg vorbis opus opusfile ncurses naclsdk' base_linux_armhf_default_packages="${base_linux_arm64_default_packages}" all_linux_armhf_default_packages="${all_linux_arm64_default_packages}" @@ -1480,7 +1482,7 @@ errorHelp() { \tbuild-macos — platforms buildable on macos: ${macos_build_platforms} Packages: - \tpkgconfig nasm zlib gmp nettle curl sdl2 glew png jpeg webp openal ogg vorbis opus opusfile naclsdk wasisdk wasmtime + \tpkgconfig nasm zlib gmp nettle curl sdl3 glew png jpeg webp openal ogg vorbis opus opusfile naclsdk wasisdk wasmtime Virtual packages: \tbase — build packages for pre-built binaries to be downloaded when building the game diff --git a/src/engine/client/ClientApplication.cpp b/src/engine/client/ClientApplication.cpp index eef3888473..1e50ba4a5e 100644 --- a/src/engine/client/ClientApplication.cpp +++ b/src/engine/client/ClientApplication.cpp @@ -34,7 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "client.h" #if defined(_WIN32) || defined(BUILD_GRAPHICAL_CLIENT) -#include +#include #ifdef BUILD_GRAPHICAL_CLIENT extern SDL_Window *window; #else @@ -80,14 +80,6 @@ class ClientApplication : public Application { } void Initialize() override { -#if defined(_WIN32) && defined(BUILD_GRAPHICAL_CLIENT) - // If not set, the size of the screen may be determined incorrectly for r_mode -2. - // E.g. with 125% scaling on a 1920x1080 screen, the size will be determined to be 1536x864 - // and there will be blank space on the top and right. - // Don't set this for TTY applications as they really aren't DPI aware. Let them scale. - SDL_SetHint(SDL_HINT_WINDOWS_DPI_AWARENESS, "system"); -#endif - #if defined(__linux__) && defined(BUILD_GRAPHICAL_CLIENT) // identify the game by its name in certain // volume control / power control applets, diff --git a/src/engine/client/cl_main.cpp b/src/engine/client/cl_main.cpp index d781aee3b3..c2ca2235ce 100644 --- a/src/engine/client/cl_main.cpp +++ b/src/engine/client/cl_main.cpp @@ -56,7 +56,7 @@ Maryland 20850 USA. #include #endif #ifdef BUILD_GRAPHICAL_CLIENT -#include +#include #endif #if defined(USE_MUMBLE) diff --git a/src/engine/client/key_identification.cpp b/src/engine/client/key_identification.cpp index a1b152ffc6..66c499d571 100644 --- a/src/engine/client/key_identification.cpp +++ b/src/engine/client/key_identification.cpp @@ -36,8 +36,8 @@ Maryland 20850 USA. #include "key_identification.h" -#include -#include +#include +#include namespace Keyboard { @@ -129,7 +129,7 @@ static int ParseCharacter(Str::StringRef s) // for the key on a QWERTY layout, if possible. static Key KeyFromUnprefixedCharacter(int ch) { - SDL_Scancode sc = SDL_GetScancodeFromKey(static_cast(ch)); + SDL_Scancode sc = SDL_GetScancodeFromKey(static_cast(ch), nullptr); if (sc != SDL_SCANCODE_UNKNOWN) { return Key::FromScancode(sc); } @@ -215,7 +215,7 @@ std::string KeyToString(Key key) } int GetCharForScancode(int scancode) { - int keycode = static_cast(SDL_GetKeyFromScancode(Util::enum_cast(scancode))); + int keycode = static_cast(SDL_GetKeyFromScancode(Util::enum_cast(scancode), 0, false)); // The keycode is a "large" number for keys such as Shift if (MIN_PRINTABLE_ASCII <= keycode && keycode <= UNICODE_MAX_CODE_POINT) { return keycode; diff --git a/src/engine/framework/System.cpp b/src/engine/framework/System.cpp index 3b58d98d9c..2d66f2a791 100644 --- a/src/engine/framework/System.cpp +++ b/src/engine/framework/System.cpp @@ -41,7 +41,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #ifdef _WIN32 #include -#include +#include +#include #else #include #include diff --git a/src/engine/sys/sdl_glimp.cpp b/src/engine/sys/sdl_glimp.cpp index 46ed518d52..33b5f59ca0 100644 --- a/src/engine/sys/sdl_glimp.cpp +++ b/src/engine/sys/sdl_glimp.cpp @@ -21,10 +21,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "qcommon/q_shared.h" // Include before SDL.h due to M_PI issue... -#include +#include #ifdef USE_SMP -#include +#include #endif #include "renderer/tr_local.h" @@ -36,7 +36,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "sdl_icon.h" #pragma warning(pop) -#include "SDL_syswm.h" #include "framework/CommandSystem.h" #include "framework/CvarSystem.h" @@ -186,6 +185,7 @@ static Cvar::Cvar workaround_glHardware_intel_useFirstProvokinVertex( Cvar::NONE, true ); SDL_Window *window = nullptr; +static SDL_PropertiesID windowProperties; static SDL_GLContext glContext = nullptr; #ifdef USE_SMP @@ -214,9 +214,9 @@ SMP acceleration * thread-safe OpenGL libraries. */ -static SDL_mutex *smpMutex = nullptr; -static SDL_cond *renderCommandsEvent = nullptr; -static SDL_cond *renderCompletedEvent = nullptr; +static SDL_Mutex *smpMutex = nullptr; +static SDL_Condition *renderCommandsEvent = nullptr; +static SDL_Condition *renderCompletedEvent = nullptr; static void ( *renderThreadFunction )() = nullptr; static SDL_Thread *renderThread = nullptr; @@ -269,7 +269,7 @@ bool GLimp_SpawnRenderThread( void ( *function )() ) return false; } - renderCommandsEvent = SDL_CreateCond(); + renderCommandsEvent = SDL_CreateCondition(); if ( renderCommandsEvent == nullptr ) { @@ -278,7 +278,7 @@ bool GLimp_SpawnRenderThread( void ( *function )() ) return false; } - renderCompletedEvent = SDL_CreateCond(); + renderCompletedEvent = SDL_CreateCondition(); if ( renderCompletedEvent == nullptr ) { @@ -323,13 +323,13 @@ void GLimp_ShutdownRenderThread() if ( renderCommandsEvent != nullptr ) { - SDL_DestroyCond( renderCommandsEvent ); + SDL_DestroyCondition( renderCommandsEvent ); renderCommandsEvent = nullptr; } if ( renderCompletedEvent != nullptr ) { - SDL_DestroyCond( renderCompletedEvent ); + SDL_DestroyCondition( renderCompletedEvent ); renderCompletedEvent = nullptr; } @@ -356,11 +356,11 @@ void *GLimp_RendererSleep() smpDataReady = false; // after this, the front end can exit GLimp_FrontEndSleep - SDL_CondSignal( renderCompletedEvent ); + SDL_SignalCondition( renderCompletedEvent ); while ( !smpDataReady ) { - SDL_CondWait( renderCommandsEvent, smpMutex ); + SDL_WaitCondition( renderCommandsEvent, smpMutex ); } data = ( void * ) smpData; @@ -383,7 +383,7 @@ void GLimp_FrontEndSleep() { while ( smpData ) { - SDL_CondWait( renderCompletedEvent, smpMutex ); + SDL_WaitCondition( renderCompletedEvent, smpMutex ); } } SDL_UnlockMutex( smpMutex ); @@ -417,7 +417,7 @@ void GLimp_WakeRenderer( void *data ) smpDataReady = true; // after this, the renderer can continue through GLimp_RendererSleep - SDL_CondSignal( renderCommandsEvent ); + SDL_SignalCondition( renderCommandsEvent ); } SDL_UnlockMutex( smpMutex ); } @@ -564,10 +564,8 @@ static void SetSwapInterval( int swapInterval ) About how to deal with errors: - > If an application requests adaptive vsync and the system - > does not support it, this function will fail and return -1. - > In such a case, you should probably retry the call with 1 - > for the interval. + > Returns true on success or false on failure; + > call SDL_GetError() for more information. > -- https://wiki.libsdl.org/SDL_GL_SetSwapInterval Given what's written in Swap Interval Khronos page, setting r_finish @@ -588,7 +586,7 @@ static void SetSwapInterval( int swapInterval ) int sign = swapInterval < 0 ? -1 : 1; int interval = std::abs( swapInterval ); - while ( SDL_GL_SetSwapInterval( sign * interval ) == -1 ) + while ( !SDL_GL_SetSwapInterval( sign * interval ) ) { if ( sign == -1 ) { @@ -655,55 +653,68 @@ GLimp_DetectAvailableModes */ static bool GLimp_DetectAvailableModes() { - char buf[ MAX_STRING_CHARS ] = { 0 }; - SDL_Rect modes[ 128 ]; - int numModes = 0; - int i; - SDL_DisplayMode windowMode; - int display; + constexpr int maxModes = 128; + SDL_Rect modes[ maxModes ]; - display = SDL_GetWindowDisplayIndex( window ); + SDL_DisplayID display = SDL_GetDisplayForWindow( window ); - if ( SDL_GetWindowDisplayMode( window, &windowMode ) < 0 ) + int allModes; + SDL_DisplayMode **displayModes = SDL_GetFullscreenDisplayModes( display, &allModes ); + + if ( !displayModes ) { - logger.Warn("Couldn't get window display mode: %s", SDL_GetError() ); - /* FIXME: returning true means the engine will crash if the window size is - larger than what the GPU can support, but we need to not fail to open a window - with a size the GPU can handle even if not using native screen resolutions. */ - return true; + Sys::Error( "Couldn't get display modes: %s", SDL_GetError() ); } - for ( i = 0; i < SDL_GetNumDisplayModes( display ); i++ ) + int numModes = 0; + for ( int i = 0; i < allModes; i++ ) { - SDL_DisplayMode mode; - - if ( SDL_GetDisplayMode( display, i, &mode ) < 0 ) - { - continue; - } + SDL_DisplayMode *mode = displayModes[ i ]; - if ( !mode.w || !mode.h ) + if ( !mode->w || !mode->h ) { + // FIXME is this really a thing? I don't see it in SDL2 or SDL3 documentation logger.Notice("Display supports any resolution" ); + SDL_free( displayModes ); return true; } - if ( windowMode.format != mode.format || windowMode.refresh_rate != mode.refresh_rate ) + if ( numModes == 0 ) + { + modes[ numModes ].w = mode->w; + modes[ numModes ].h = mode->h; + } + else { - continue; + if ( modes[ numModes - 1 ].w == mode->w + && modes[ numModes - 1 ].h == mode->h ) + { + continue; + } + + modes[ numModes ].w = mode->w; + modes[ numModes ].h = mode->h; } - modes[ numModes ].w = mode.w; - modes[ numModes ].h = mode.h; numModes++; + + if ( numModes == maxModes ) + { + logger.Warn( "More than %d modes", maxModes ); + break; + } } + SDL_free( displayModes ); + if ( numModes > 1 ) { qsort( modes, numModes, sizeof( SDL_Rect ), GLimp_CompareModes ); } - for ( i = 0; i < numModes; i++ ) + char buf[ MAX_STRING_CHARS ] = { 0 }; + + for ( int i = 0; i < numModes; i++ ) { const char *newModeString = va( "%ux%u ", modes[ i ].w, modes[ i ].h ); @@ -798,6 +809,15 @@ static void GLimp_SetAttributes( const glConfiguration &configuration ) } } +// Copied from https://github.com/libsdl-org/SDL/blob/main/docs/README-migration.md +static SDL_Surface *SDL_CreateRGBSurfaceFrom( + void *pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask ) +{ + return SDL_CreateSurfaceFrom( width, height, + SDL_GetPixelFormatForMasks( depth, Rmask, Gmask, Bmask, Amask ), + pixels, pitch); +} + static bool GLimp_CreateWindow( bool fullscreen, bool bordered, const glConfiguration &configuration ) { /* The requested attributes should be set before creating @@ -851,20 +871,46 @@ static bool GLimp_CreateWindow( bool fullscreen, bool bordered, const glConfigur } } + int numDisplays; + SDL_DisplayID *displayIDs = SDL_GetDisplays( &numDisplays ); + + if ( !displayIDs ) + { + Sys::Error( "SDL_GetDisplays failed: %s\n", SDL_GetError() ); + } + + SDL_DisplayID displayID = + r_displayIndex->integer < numDisplays || r_displayIndex->integer > numDisplays + ? displayIDs[ r_displayIndex->integer ] + : 0; // 0 implies primary display + + SDL_free( displayIDs ); + int x, y; if ( r_centerWindow->integer ) { // center window on specified display - x = SDL_WINDOWPOS_CENTERED_DISPLAY( r_displayIndex->integer ); - y = SDL_WINDOWPOS_CENTERED_DISPLAY( r_displayIndex->integer ); + x = SDL_WINDOWPOS_CENTERED_DISPLAY( displayID ); + y = SDL_WINDOWPOS_CENTERED_DISPLAY( displayID ); } else { - x = SDL_WINDOWPOS_UNDEFINED_DISPLAY( r_displayIndex->integer ); - y = SDL_WINDOWPOS_UNDEFINED_DISPLAY( r_displayIndex->integer ); + x = SDL_WINDOWPOS_UNDEFINED_DISPLAY( displayID ); + y = SDL_WINDOWPOS_UNDEFINED_DISPLAY( displayID ); } - window = SDL_CreateWindow( CLIENT_WINDOW_TITLE, x, y, windowConfig.vidWidth, windowConfig.vidHeight, flags ); + windowProperties = SDL_CreateProperties(); + if ( !windowProperties ) + { + Sys::Error( "SDL_CreateProperties failed" ); + } + SDL_SetStringProperty( windowProperties, SDL_PROP_WINDOW_CREATE_TITLE_STRING, CLIENT_WINDOW_TITLE ); + SDL_SetNumberProperty( windowProperties, SDL_PROP_WINDOW_CREATE_X_NUMBER, x ); + SDL_SetNumberProperty( windowProperties, SDL_PROP_WINDOW_CREATE_Y_NUMBER, y ); + SDL_SetNumberProperty( windowProperties, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, windowConfig.vidWidth ); + SDL_SetNumberProperty( windowProperties, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, windowConfig.vidHeight ); + SDL_SetNumberProperty( windowProperties, SDL_PROP_WINDOW_CREATE_FLAGS_NUMBER, flags ); + window = SDL_CreateWindowWithProperties( windowProperties ); if ( window ) { @@ -883,12 +929,14 @@ static bool GLimp_CreateWindow( bool fullscreen, bool bordered, const glConfigur windowType ? windowType : "", windowType ? " ": "" ); logger.Warn("SDL_CreateWindow failed: %s", SDL_GetError() ); + SDL_DestroyProperties( windowProperties ); + windowProperties = 0; return false; } SDL_SetWindowIcon( window, icon ); - SDL_FreeSurface( icon ); + SDL_DestroySurface( icon ); return true; } @@ -897,7 +945,7 @@ static void GLimp_DestroyContextIfExists() { if ( glContext != nullptr ) { - SDL_GL_DeleteContext( glContext ); + SDL_GL_DestroyContext( glContext ); glContext = nullptr; } } @@ -915,6 +963,8 @@ static void GLimp_DestroyWindowIfExists() logger.Debug("Destroying %d×%d SDL window at %d,%d", w, h, x, y ); SDL_DestroyWindow( window ); window = nullptr; + SDL_DestroyProperties( windowProperties ); + windowProperties = 0; } } @@ -1008,9 +1058,7 @@ static bool GLimp_RecreateWindowWhenChange( const bool fullscreen, const bool bo if ( bordered != currentBordered ) { - SDL_bool sdlBordered = bordered ? SDL_TRUE : SDL_FALSE; - - SDL_SetWindowBordered( window, sdlBordered ); + SDL_SetWindowBordered( window, bordered ); const char* windowType = bordered ? "bordered" : "borderless"; logger.Debug( "SDL window set as %s.", windowType ); @@ -1024,30 +1072,46 @@ static bool GLimp_RecreateWindowWhenChange( const bool fullscreen, const bool bo static rserr_t GLimp_SetModeAndResolution( const int mode ) { - SDL_DisplayMode desktopMode; + int numDisplays; + SDL_DisplayID *displayIDs = SDL_GetDisplays( &numDisplays ); + + if ( !displayIDs ) + { + Sys::Error( "SDL_GetDisplays failed: %s\n", SDL_GetError() ); + } - if ( SDL_GetDesktopDisplayMode( r_displayIndex->integer, &desktopMode ) == 0 ) + if ( numDisplays <= 0 ) { - windowConfig.displayAspect = ( float ) desktopMode.w / ( float ) desktopMode.h; + Sys::Error( "SDL_GetDisplays returned 0 displays" ); + } + + SDL_DisplayID displayID = displayIDs[ Math::Clamp( r_displayIndex->integer, 0, numDisplays - 1 ) ]; + + SDL_free( displayIDs ); + + const SDL_DisplayMode *desktopMode = SDL_GetDesktopDisplayMode( displayID ); + + if ( desktopMode ) + { + windowConfig.displayAspect = ( float ) desktopMode->w / ( float ) desktopMode->h; logger.Notice( "Display aspect: %.3f", windowConfig.displayAspect ); } else { - memset( &desktopMode, 0, sizeof( SDL_DisplayMode ) ); windowConfig.displayAspect = 1.333f; logger.Warn("Cannot determine display aspect, assuming %.3f: %s", windowConfig.displayAspect, SDL_GetError() ); } - windowConfig.displayWidth = desktopMode.w; - windowConfig.displayHeight = desktopMode.h; + windowConfig.displayWidth = desktopMode->w; + windowConfig.displayHeight = desktopMode->h; if ( mode == -2 ) { // use desktop video resolution - if ( desktopMode.h > 0 ) + if ( desktopMode->h > 0 ) { - windowConfig.vidWidth = desktopMode.w; - windowConfig.vidHeight = desktopMode.h; + windowConfig.vidWidth = desktopMode->w; + windowConfig.vidHeight = desktopMode->h; } else { @@ -1704,8 +1768,6 @@ GLimp_StartDriverAndSetMode */ static rserr_t GLimp_StartDriverAndSetMode( int mode, bool fullscreen, bool bordered ) { - int numDisplays; - #if !defined(_WIN32) && !defined(__APPLE__) /* Let X11 and Wayland desktops (Linux, FreeBSD…) associate the game window with the XDG .desktop file, with the proper name and icon. @@ -1723,11 +1785,18 @@ static rserr_t GLimp_StartDriverAndSetMode( int mode, bool fullscreen, bool bord if ( !SDL_WasInit( SDL_INIT_VIDEO ) ) { const char *driverName; - SDL_version v; - SDL_GetVersion( &v ); + + const int linked = SDL_GetVersion(); + const int compiled = SDL_VERSION; logger.Notice("SDL_Init( SDL_INIT_VIDEO )... " ); - logger.Notice("Using SDL version %u.%u.%u", v.major, v.minor, v.patch ); + logger.Notice("Using SDL version %d.%d.%d (compiled against SDL version %d.%d.%d)", + SDL_VERSIONNUM_MAJOR(linked), + SDL_VERSIONNUM_MINOR(linked), + SDL_VERSIONNUM_MICRO(linked), + SDL_VERSIONNUM_MAJOR(compiled), + SDL_VERSIONNUM_MINOR(compiled), + SDL_VERSIONNUM_MICRO(compiled)); /* It is recommended to test for negative value and not just -1. @@ -1739,7 +1808,7 @@ static rserr_t GLimp_StartDriverAndSetMode( int mode, bool fullscreen, bool bord > if (SDL_Init(SDL_INIT_EVERYTHING) < 0) > -- https://wiki.libsdl.org/SDL_GetError */ - if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) + if ( !SDL_Init( SDL_INIT_VIDEO ) ) { Sys::Error("SDL_Init( SDL_INIT_VIDEO ) failed: %s", SDL_GetError() ); } @@ -1755,11 +1824,12 @@ static rserr_t GLimp_StartDriverAndSetMode( int mode, bool fullscreen, bool bord Cvar_Set( "r_sdlDriver", driverName ); } - numDisplays = SDL_GetNumVideoDisplays(); + int numDisplays; + SDL_DisplayID *displayIDs = SDL_GetDisplays( &numDisplays ); - if ( numDisplays <= 0 ) + if ( !displayIDs ) { - Sys::Error( "SDL_GetNumVideoDisplays failed: %s\n", SDL_GetError() ); + Sys::Error( "SDL_GetDisplays failed: %s\n", SDL_GetError() ); } #if defined(DAEMON_OPENGL_ABI) @@ -1822,7 +1892,7 @@ static GLenum debugTypes[] = }; #ifdef _WIN32 -#define DEBUG_CALLBACK_CALL APIENTRY +#define DEBUG_CALLBACK_CALL __stdcall //APIENTRY #else #define DEBUG_CALLBACK_CALL #endif @@ -2918,7 +2988,7 @@ void GLimp_HandleCvars() if ( Util::optional noBorder = r_noBorder.GetModifiedValue() ) { - SDL_bool bordered = *noBorder ? SDL_FALSE : SDL_TRUE; + bool bordered = !*noBorder; SDL_SetWindowBordered( window, bordered ); } diff --git a/src/engine/sys/sdl_input.cpp b/src/engine/sys/sdl_input.cpp index d04fd96f2d..394b527d4f 100644 --- a/src/engine/sys/sdl_input.cpp +++ b/src/engine/sys/sdl_input.cpp @@ -34,7 +34,7 @@ Maryland 20850 USA. #include "common/Common.h" -#include +#include #include "client/client.h" #include "client/key_identification.h" #include "qcommon/q_unicode.h" @@ -48,7 +48,7 @@ static Log::Logger mouseLog("client.mouse", ""); static cvar_t *in_keyboardDebug = nullptr; static SDL_Joystick *stick = nullptr; -static SDL_GameController *gamepad = nullptr; +static SDL_Gamepad *gamepad = nullptr; static cvar_t *in_nograb; @@ -68,38 +68,39 @@ static SDL_Window *window = nullptr; IN_PrintKey =============== */ -static void IN_PrintKey( const SDL_Keysym *keysym, Keyboard::Key keycodeKey, bool down ) +static void IN_PrintKey( const SDL_Keymod mod, const SDL_Scancode scancode, const SDL_Keycode eventKey, + Keyboard::Key keycodeKey, bool down ) { std::string kmods; - if ( keysym->mod & KMOD_LSHIFT ) { kmods += "KMOD_LSHIFT "; } + if ( mod & SDL_KMOD_LSHIFT ) { kmods += "KMOD_LSHIFT "; } - if ( keysym->mod & KMOD_RSHIFT ) { kmods += "KMOD_RSHIFT "; } + if ( mod & SDL_KMOD_RSHIFT ) { kmods += "KMOD_RSHIFT "; } - if ( keysym->mod & KMOD_LCTRL ) { kmods += "KMOD_LCTRL "; } + if ( mod & SDL_KMOD_LCTRL ) { kmods += "KMOD_LCTRL "; } - if ( keysym->mod & KMOD_RCTRL ) { kmods += "KMOD_RCTRL "; } + if ( mod & SDL_KMOD_RCTRL ) { kmods += "KMOD_RCTRL "; } - if ( keysym->mod & KMOD_LALT ) { kmods += "KMOD_LALT "; } + if ( mod & SDL_KMOD_LALT ) { kmods += "KMOD_LALT "; } - if ( keysym->mod & KMOD_RALT ) { kmods += "KMOD_RALT "; } + if ( mod & SDL_KMOD_RALT ) { kmods += "KMOD_RALT "; } - if ( keysym->mod & KMOD_LGUI ) { kmods += "KMOD_LGUI "; } + if ( mod & SDL_KMOD_LGUI ) { kmods += "KMOD_LGUI "; } - if ( keysym->mod & KMOD_RGUI ) { kmods += "KMOD_RGUI "; } + if ( mod & SDL_KMOD_RGUI ) { kmods += "KMOD_RGUI "; } - if ( keysym->mod & KMOD_NUM ) { kmods += "KMOD_NUM" ; } + if ( mod & SDL_KMOD_NUM ) { kmods += "KMOD_NUM" ; } - if ( keysym->mod & KMOD_CAPS ) { kmods += "KMOD_CAPS "; } + if ( mod & SDL_KMOD_CAPS ) { kmods += "KMOD_CAPS "; } - if ( keysym->mod & KMOD_MODE ) { kmods += "KMOD_MODE "; } + if ( mod & SDL_KMOD_MODE ) { kmods += "KMOD_MODE "; } - if ( keysym->mod & KMOD_RESERVED ) { kmods += "KMOD_RESERVED "; } + // if ( mod & SDL_KMOD_RESERVED ) { kmods += "KMOD_RESERVED "; } Log::defaultLogger.WithoutSuppression().Notice( "%s%c scancode = 0x%03x | SDL name = \"%s\" | keycode bind = %s | scancode bind = %s", - kmods, down ? '+' : '-', keysym->scancode, SDL_GetKeyName( keysym->sym ), - KeyToString( keycodeKey ), KeyToString( Keyboard::Key::FromScancode( keysym->scancode ))); + kmods, down ? '+' : '-', scancode, SDL_GetKeyName( eventKey ), + KeyToString( keycodeKey ), KeyToString( Keyboard::Key::FromScancode( scancode ))); } /* @@ -121,22 +122,22 @@ static bool IN_IsConsoleKey( Keyboard::Key key ) } // Translates based on keycode, not scancode. -static Keyboard::Key IN_TranslateSDLToQ3Key( SDL_Keysym *keysym, bool down ) +static Keyboard::Key IN_TranslateSDLToQ3Key( SDL_KeyboardEvent *event, bool down ) { using Keyboard::Key; Key key; - if ( keysym->sym == SDLK_DELETE ) // SDLK_DELETE is anomalously located in the Unicode range. + if ( event->key == SDLK_DELETE ) // SDLK_DELETE is anomalously located in the Unicode range. { key = Key(K_DEL); } - else if ( keysym->sym >= SDLK_SPACE && keysym->sym < UNICODE_MAX_CODE_POINT ) + else if ( event->key >= SDLK_SPACE && event->key < UNICODE_MAX_CODE_POINT ) { - key = Key::FromCharacter(keysym->sym); + key = Key::FromCharacter( event->key ); } else { - switch ( keysym->sym ) + switch ( event->key ) { case SDLK_PAGEUP: key = Key(K_PGUP); @@ -393,7 +394,7 @@ static Keyboard::Key IN_TranslateSDLToQ3Key( SDL_Keysym *keysym, bool down ) if ( in_keyboardDebug->integer ) { - IN_PrintKey( keysym, key, down ); + IN_PrintKey( event->mod, event->scancode, event->key, key, down ); } return key; @@ -454,21 +455,21 @@ void IN_SetMouseMode(MouseMode newMode) switch ( newMode ) { case MouseMode::SystemCursor: - SDL_ShowCursor( SDL_ENABLE ); - SDL_SetWindowGrab( window, SDL_FALSE ); - SDL_SetRelativeMouseMode( SDL_FALSE ); + SDL_ShowCursor(); + SDL_SetWindowMouseGrab( window, false ); + SDL_SetWindowRelativeMouseMode( window, false ); break; case MouseMode::CustomCursor: - SDL_ShowCursor( SDL_DISABLE ); - SDL_SetWindowGrab( window, SDL_FALSE ); - SDL_SetRelativeMouseMode( SDL_FALSE ); + SDL_HideCursor(); + SDL_SetWindowMouseGrab( window, false ); + SDL_SetWindowRelativeMouseMode( window, false ); break; case MouseMode::Deltas: - SDL_ShowCursor( SDL_DISABLE ); - SDL_SetWindowGrab( window, SDL_TRUE ); - SDL_SetRelativeMouseMode( SDL_TRUE ); + SDL_HideCursor(); + SDL_SetWindowMouseGrab( window, true ); + SDL_SetWindowRelativeMouseMode( window, true ); break; } @@ -552,9 +553,9 @@ struct unsigned int oldhats; } stick_state; -static const char* JoystickNameForIndex(int index) +static const char* JoystickNameForID( SDL_JoystickID id ) { - const char* name = SDL_JoystickNameForIndex(index); + const char* name = SDL_GetJoystickNameForID( id ); return name ? name : ""; } @@ -565,12 +566,9 @@ IN_InitJoystick */ static void IN_InitJoystick() { - int i = 0; - int total = 0; - if ( stick != nullptr ) { - SDL_JoystickClose( stick ); + SDL_CloseJoystick( stick ); } stick = nullptr; @@ -592,7 +590,7 @@ static void IN_InitJoystick() { Log::Debug( "Calling SDL_Init(SDL_INIT_JOYSTICK)..." ); - if ( SDL_Init( SDL_INIT_JOYSTICK ) < 0 ) + if ( !SDL_Init( SDL_INIT_JOYSTICK ) ) { Log::Warn( "SDL_Init(SDL_INIT_JOYSTICK) failed: %s", SDL_GetError() ); return; @@ -601,24 +599,33 @@ static void IN_InitJoystick() Log::Debug( "SDL_Init(SDL_INIT_JOYSTICK) passed." ); } - total = SDL_NumJoysticks(); + int total = 0; + SDL_JoystickID* ids = SDL_GetJoysticks( &total ); Log::Debug( "%d possible joysticks", total ); - for ( i = 0; i < total; i++ ) + for ( int i = 0; i < total; i++ ) { - Log::Debug( "[%d] %s", i, JoystickNameForIndex( i ) ); + Log::Debug( "[%d] %s", i, JoystickNameForID( ids[i] ) ); } in_joystickNo = Cvar_Get( "in_joystickNo", "0", 0 ); + in_joystickUseAnalog = Cvar_Get( "in_joystickUseAnalog", "0", 0 ); + + if ( total <= 0 ) + { + SDL_free( ids ); + return; + } if ( in_joystickNo->integer < 0 || in_joystickNo->integer >= total ) { Cvar_Set( "in_joystickNo", "0" ); } - in_joystickUseAnalog = Cvar_Get( "in_joystickUseAnalog", "0", 0 ); + SDL_JoystickID id = ids[ in_joystickNo->integer ]; + SDL_free( ids ); - stick = SDL_JoystickOpen( in_joystickNo->integer ); + stick = SDL_OpenJoystick( id ); if ( stick == nullptr ) { @@ -626,26 +633,26 @@ static void IN_InitJoystick() return; } - if ( SDL_IsGameController( in_joystickNo->integer ) ) + if ( SDL_IsGamepad( id ) ) { - gamepad = SDL_GameControllerOpen( in_joystickNo->integer ); + gamepad = SDL_OpenGamepad( id ); if ( gamepad ) { Cvar_Set( "in_gameControllerAvailable", "1" ); - SDL_GameControllerEventState( SDL_QUERY ); + SDL_GamepadEventsEnabled(); } } Log::Debug( "Joystick %d opened", in_joystickNo->integer ); - Log::Debug( "Name: %s", JoystickNameForIndex( in_joystickNo->integer ) ); - Log::Debug( "Axes: %d", SDL_JoystickNumAxes( stick ) ); - Log::Debug( "Hats: %d", SDL_JoystickNumHats( stick ) ); - Log::Debug( "Buttons: %d", SDL_JoystickNumButtons( stick ) ); - Log::Debug( "Balls: %d", SDL_JoystickNumBalls( stick ) ); + Log::Debug( "Name: %s", JoystickNameForID( id ) ); + Log::Debug( "Axes: %d", SDL_GetNumJoystickAxes( stick ) ); + Log::Debug( "Hats: %d", SDL_GetNumJoystickHats( stick ) ); + Log::Debug( "Buttons: %d", SDL_GetNumJoystickButtons( stick ) ); + Log::Debug( "Balls: %d", SDL_GetNumJoystickBalls( stick ) ); Log::Debug( "Use Analog: %s", in_joystickUseAnalog->integer ? "Yes" : "No" ); Log::Debug( "Use SDL2 GameController mappings: %s", gamepad ? "Yes" : "No" ); - SDL_JoystickEventState( SDL_QUERY ); + SDL_GamepadEventsEnabled(); } /* @@ -657,12 +664,12 @@ static void IN_ShutdownJoystick() { if ( gamepad ) { - SDL_GameControllerClose( gamepad ); + SDL_CloseGamepad( gamepad ); gamepad = nullptr; } if ( stick ) { - SDL_JoystickClose( stick ); + SDL_CloseJoystick( stick ); stick = nullptr; } @@ -709,10 +716,10 @@ static void IN_JoyMove() return; } - SDL_JoystickUpdate(); + SDL_UpdateJoysticks(); // update the ball state. - total = SDL_JoystickNumBalls( stick ); + total = SDL_GetNumJoystickBalls( stick ); if ( total > 0 ) { @@ -723,7 +730,7 @@ static void IN_JoyMove() { int dx = 0; int dy = 0; - SDL_JoystickGetBall( stick, i, &dx, &dy ); + SDL_GetJoystickBall( stick, i, &dx, &dy ); balldx += dx; balldy += dy; } @@ -750,7 +757,7 @@ static void IN_JoyMove() } // now query the stick buttons... - total = SDL_JoystickNumButtons( stick ); + total = SDL_GetNumJoystickButtons( stick ); if ( total > 0 ) { @@ -761,7 +768,7 @@ static void IN_JoyMove() for ( i = 0; i < total; i++ ) { - bool pressed = ( SDL_JoystickGetButton( stick, i ) != 0 ); + bool pressed = ( SDL_GetJoystickButton( stick, i ) != 0 ); if ( pressed != stick_state.buttons[ i ] ) { @@ -773,7 +780,7 @@ static void IN_JoyMove() } // look at the hats... - total = SDL_JoystickNumHats( stick ); + total = SDL_GetNumJoystickHats( stick ); if ( total > 0 ) { @@ -781,7 +788,7 @@ static void IN_JoyMove() for ( i = 0; i < total; i++ ) { - ( ( Uint8 * ) &hats ) [ i ] = SDL_JoystickGetHat( stick, i ); + ( ( Uint8 * ) &hats ) [ i ] = SDL_GetJoystickHat( stick, i ); } } @@ -885,7 +892,7 @@ static void IN_JoyMove() stick_state.oldhats = hats; // finally, look at the axes... - total = SDL_JoystickNumAxes( stick ); + total = SDL_GetNumJoystickAxes( stick ); if ( total > 0 ) { @@ -893,7 +900,7 @@ static void IN_JoyMove() for ( i = 0; i < total; i++ ) { - Sint16 axis = SDL_JoystickGetAxis( stick, i ); + Sint16 axis = SDL_GetJoystickAxis( stick, i ); if ( !in_joystickUseAnalog->integer ) { @@ -945,9 +952,9 @@ static void IN_JoyMove() stick_state.oldaxes = axes; } -static void IN_GameControllerAxis( SDL_GameControllerAxis controllerAxis, joystickAxis_t gameAxis, float scale ) +static void IN_GameControllerAxis( SDL_GamepadAxis controllerAxis, joystickAxis_t gameAxis, float scale ) { - Sint16 axis = SDL_GameControllerGetAxis( gamepad, controllerAxis ); + Sint16 axis = SDL_GetGamepadAxis( gamepad, controllerAxis ); float f = ( ( float ) axis ) / 32767.0f; if ( f > -in_joystickThreshold->value && f < in_joystickThreshold->value ) @@ -965,12 +972,12 @@ static void IN_GameControllerAxis( SDL_GameControllerAxis controllerAxis, joysti } } -static int IN_GameControllerAxisToButton( SDL_GameControllerAxis controllerAxis, keyNum_t key ) +static int IN_GameControllerAxisToButton( SDL_GamepadAxis controllerAxis, keyNum_t key ) { using Keyboard::Key; unsigned int axes = 0; - Sint16 axis = SDL_GameControllerGetAxis( gamepad, controllerAxis ); + Sint16 axis = SDL_GetGamepadAxis( gamepad, controllerAxis ); float f = ( ( float ) axis ) / 32767.0f; if ( f > in_gameControllerTriggerDeadzone->value ) @@ -984,7 +991,7 @@ static int IN_GameControllerAxisToButton( SDL_GameControllerAxis controllerAxis, if ( in_gameControllerDebug->integer ) { Log::Notice( "GameController axis = %s to key = Q:0x%02x(%s), value = %f", - SDL_GameControllerGetStringForAxis( controllerAxis ), key, + SDL_GetGamepadStringForAxis( controllerAxis ), key, Keyboard::KeyToString( Key(key) ), f ); } } @@ -995,7 +1002,7 @@ static int IN_GameControllerAxisToButton( SDL_GameControllerAxis controllerAxis, if ( in_gameControllerDebug->integer ) { Log::Notice( "GameController axis = %s to key = Q:0x%02x(%s), value = %f", - SDL_GameControllerGetStringForAxis( controllerAxis ), key, + SDL_GetGamepadStringForAxis( controllerAxis ), key, Keyboard::KeyToString( Key(key) ), f ); } } @@ -1019,11 +1026,11 @@ static void IN_GameControllerMove() return; } - SDL_GameControllerUpdate(); + SDL_UpdateGamepads(); for ( i = 0; i < (K_CONTROLLER_MAX - K_CONTROLLER_A); i++ ) { - bool pressed = SDL_GameControllerGetButton( gamepad, Util::enum_cast(i) ); + bool pressed = SDL_GetGamepadButton( gamepad, Util::enum_cast(i) ); if ( pressed != stick_state.buttons[ i ] ) { @@ -1032,7 +1039,7 @@ static void IN_GameControllerMove() if ( in_gameControllerDebug->integer ) { Log::Notice( "GameController button %s = %s", - SDL_GameControllerGetStringForButton( Util::enum_cast(i) ), + SDL_GetGamepadStringForButton( Util::enum_cast< SDL_GamepadButton >(i) ), pressed ? "Pressed" : "Released" ); } @@ -1041,15 +1048,15 @@ static void IN_GameControllerMove() } // use left stick for strafing - IN_GameControllerAxis( SDL_CONTROLLER_AXIS_LEFTX, joystickAxis_t::AXIS_SIDE, 127 ); - IN_GameControllerAxis( SDL_CONTROLLER_AXIS_LEFTY, joystickAxis_t::AXIS_FORWARD, -127 ); + IN_GameControllerAxis( SDL_GAMEPAD_AXIS_LEFTX, joystickAxis_t::AXIS_SIDE, 127 ); + IN_GameControllerAxis( SDL_GAMEPAD_AXIS_LEFTY, joystickAxis_t::AXIS_FORWARD, -127 ); // use right stick for viewing - IN_GameControllerAxis( SDL_CONTROLLER_AXIS_RIGHTX, joystickAxis_t::AXIS_YAW, -127 ); - IN_GameControllerAxis( SDL_CONTROLLER_AXIS_RIGHTY, joystickAxis_t::AXIS_PITCH, 127 ); + IN_GameControllerAxis( SDL_GAMEPAD_AXIS_RIGHTX, joystickAxis_t::AXIS_YAW, -127 ); + IN_GameControllerAxis( SDL_GAMEPAD_AXIS_RIGHTY, joystickAxis_t::AXIS_PITCH, 127 ); - axes |= IN_GameControllerAxisToButton( SDL_CONTROLLER_AXIS_TRIGGERLEFT, K_CONTROLLER_LT ); - axes |= IN_GameControllerAxisToButton( SDL_CONTROLLER_AXIS_TRIGGERRIGHT, K_CONTROLLER_RT ); + axes |= IN_GameControllerAxisToButton( SDL_GAMEPAD_AXIS_LEFT_TRIGGER, K_CONTROLLER_LT ); + axes |= IN_GameControllerAxisToButton( SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, K_CONTROLLER_RT ); /* Save for future generations. */ stick_state.oldaxes = axes; @@ -1080,12 +1087,12 @@ static void IN_ProcessEvents( bool dropInput ) { switch ( e.type ) { - case SDL_KEYDOWN: + case SDL_EVENT_KEY_DOWN: if ( !dropInput ) { // Send events for both scancode- and keycode-based Keys - Key kScan = Keyboard::Key::FromScancode( e.key.keysym.scancode ); - Key kKeycode = IN_TranslateSDLToQ3Key( &e.key.keysym, true ); + Key kScan = Keyboard::Key::FromScancode( e.key.scancode ); + Key kKeycode = IN_TranslateSDLToQ3Key( &e.key, true ); bool consoleFound = false; for (Key k: {kScan, kKeycode} ) { if ( IN_IsConsoleKey( k ) && !keys[ Key(K_ALT) ].down) { @@ -1104,30 +1111,30 @@ static void IN_ProcessEvents( bool dropInput ) } break; - case SDL_KEYUP: + case SDL_EVENT_KEY_UP: if ( !dropInput ) { QueueKeyEvent( - Keyboard::Key::FromScancode( e.key.keysym.scancode ), - IN_TranslateSDLToQ3Key( &e.key.keysym, false ), + Keyboard::Key::FromScancode( e.key.scancode ), + IN_TranslateSDLToQ3Key( &e.key, false ), false, false ); } break; - case SDL_TEXTINPUT: + case SDL_EVENT_TEXT_INPUT: if ( !lastEventWasConsoleKeyDown ) { - char *c = e.text.text; + std::string text = e.text.text; - while ( *c ) - { + const char* c = text.c_str(); + while ( *c ) { int width = Q_UTF8_Width( c ); Com_QueueEvent( Util::make_unique( Q_UTF8_CodePoint( c ) ) ); c += width; } } break; - case SDL_MOUSEMOTION: + case SDL_EVENT_MOUSE_MOTION: if ( !dropInput ) { if ( mouse_mode != MouseMode::Deltas ) @@ -1141,8 +1148,8 @@ static void IN_ProcessEvents( bool dropInput ) } break; - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: + case SDL_EVENT_MOUSE_BUTTON_DOWN: + case SDL_EVENT_MOUSE_BUTTON_UP: if ( !dropInput ) { keyNum_t b; @@ -1172,10 +1179,10 @@ static void IN_ProcessEvents( bool dropInput ) b = Util::enum_cast(K_AUX1 + ( e.button.button - ( SDL_BUTTON_X2 + 1 ) ) % 16); break; } - QueueKeyEvent( b, e.type == SDL_MOUSEBUTTONDOWN ); + QueueKeyEvent( b, e.type == SDL_EVENT_MOUSE_BUTTON_DOWN ); } break; - case SDL_MOUSEWHEEL: + case SDL_EVENT_MOUSE_WHEEL: // FIXME: mouse wheel support shouldn't use keys! if ( e.wheel.y > 0 ) { @@ -1189,43 +1196,38 @@ static void IN_ProcessEvents( bool dropInput ) } break; - case SDL_WINDOWEVENT: - switch( e.window.event ) + case SDL_EVENT_WINDOW_RESIZED: + extern cvar_t* r_allowResize; + // Toggling r_fullscreen does not work well when r_allowResize is enabled - + // it generates spurious resize events. + if ( r_allowResize->integer ) { - case SDL_WINDOWEVENT_RESIZED: - extern cvar_t* r_allowResize; - // Toggling r_fullscreen does not work well when r_allowResize is enabled - - // it generates spurious resize events. - if ( r_allowResize->integer ) - { - char width[32], height[32]; - Com_sprintf( width, sizeof( width ), "%d", e.window.data1 ); - Com_sprintf( height, sizeof( height ), "%d", e.window.data2 ); - Cvar_Set( "r_customwidth", width ); - Cvar_Set( "r_customheight", height ); - Cvar_Set( "r_mode", "-1" ); - } - break; + char width[32], height[32]; + Com_sprintf( width, sizeof( width ), "%d", e.window.data1 ); + Com_sprintf( height, sizeof( height ), "%d", e.window.data2 ); + Cvar_Set( "r_customwidth", width ); + Cvar_Set( "r_customheight", height ); + Cvar_Set( "r_mode", "-1" ); + } + break; - case SDL_WINDOWEVENT_MINIMIZED: Cvar_SetValue( "com_minimized", 1 ); break; - case SDL_WINDOWEVENT_RESTORED: - case SDL_WINDOWEVENT_MAXIMIZED: Cvar_SetValue( "com_minimized", 0 ); break; - case SDL_WINDOWEVENT_FOCUS_LOST: Cvar_SetValue( "com_unfocused", 1 ); break; - case SDL_WINDOWEVENT_FOCUS_GAINED: + case SDL_EVENT_WINDOW_MINIMIZED: Cvar_SetValue( "com_minimized", 1 ); break; + case SDL_EVENT_WINDOW_RESTORED: + case SDL_EVENT_WINDOW_MAXIMIZED: Cvar_SetValue( "com_minimized", 0 ); break; + case SDL_EVENT_WINDOW_FOCUS_LOST: Cvar_SetValue( "com_unfocused", 1 ); break; + case SDL_EVENT_WINDOW_FOCUS_GAINED: - Cvar_SetValue( "com_unfocused", 0 ); + Cvar_SetValue( "com_unfocused", 0 ); - // HACK: if the window is focused, it can't be minimized. - // fixes - // * https://github.com/DaemonEngine/Daemon/issues/408 - // * https://github.com/Unvanquished/Unvanquished/issues/1136 - // and maybe others - Cvar_SetValue( "com_minimized", 0 ); + // HACK: if the window is focused, it can't be minimized. + // fixes + // * https://github.com/DaemonEngine/Daemon/issues/408 + // * https://github.com/Unvanquished/Unvanquished/issues/1136 + // and maybe others + Cvar_SetValue( "com_minimized", 0 ); - break; - } break; - case SDL_QUIT: + case SDL_EVENT_QUIT: Cmd::ExecuteCommand("quit Closed window"); break; default: @@ -1236,7 +1238,7 @@ static void IN_ProcessEvents( bool dropInput ) } bool IN_IsNumLockOn() { - return SDL_GetModState() & KMOD_NUM; + return SDL_GetModState() & SDL_KMOD_NUM; } /* @@ -1319,7 +1321,7 @@ void IN_Init( void *windowData ) in_gameControllerTriggerDeadzone = Cvar_Get( "in_gameControllerTriggerDeadzone", "0.5", 0); in_gameControllerDebug = Cvar_Get( "in_gameControllerDebug", "0", CVAR_TEMP ); - SDL_StartTextInput(); + SDL_StartTextInput( window ); IN_SetMouseMode( MouseMode::SystemCursor ); appState = SDL_GetWindowFlags( window ); @@ -1342,7 +1344,7 @@ IN_Shutdown */ void IN_Shutdown() { - SDL_StopTextInput(); + SDL_StopTextInput( window ); IN_SetMouseMode(MouseMode::SystemCursor); mouse_mode_unset = true; From 7dbfd80e6ad934f82b3bfe482a2ffa1d53aec0bf Mon Sep 17 00:00:00 2001 From: slipher Date: Thu, 14 Aug 2025 22:43:09 -0500 Subject: [PATCH 33/36] sdl3: disable the "accent menu" on macOS For some reason SDL3 made a change to enable a system menu offering to input a letter with diacritics, which appears whenever you press and hold a key (for example while running). After SDL does this, call the same Objective C facility to undo the configuration change that SDL did. --- src.cmake | 4 ++++ src/engine/sys/DisableAccentMenu.m | 38 ++++++++++++++++++++++++++++++ src/engine/sys/sdl_input.cpp | 10 ++++++++ 3 files changed, 52 insertions(+) create mode 100644 src/engine/sys/DisableAccentMenu.m diff --git a/src.cmake b/src.cmake index df5b642eca..bfd5f352f6 100644 --- a/src.cmake +++ b/src.cmake @@ -356,6 +356,10 @@ set(CLIENTLIST ${RENDERERLIST} ) +if (APPLE) + set(CLIENTLIST ${CLIENTLIST} ${ENGINE_DIR}/sys/DisableAccentMenu.m) +endif() + set(CLIENTTESTLIST ${ENGINETESTLIST} ${ENGINE_DIR}/renderer/gl_shader_test.cpp ) diff --git a/src/engine/sys/DisableAccentMenu.m b/src/engine/sys/DisableAccentMenu.m new file mode 100644 index 0000000000..a8776cf3ce --- /dev/null +++ b/src/engine/sys/DisableAccentMenu.m @@ -0,0 +1,38 @@ +/* +=========================================================================== +Daemon BSD Source Code +Copyright (c) 2025, Daemon Developers +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Daemon developers nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +=========================================================================== +*/ + +#import + +void DisableAccentMenu() { + // Don't do this: https://forums.factorio.com/download/file.php?id=46540 + NSDictionary *appDefaults = [[NSDictionary alloc] initWithObjectsAndKeys: + [NSNumber numberWithBool:NO], @"ApplePressAndHoldEnabled", nil]; + [[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults]; +} diff --git a/src/engine/sys/sdl_input.cpp b/src/engine/sys/sdl_input.cpp index 394b527d4f..c673794757 100644 --- a/src/engine/sys/sdl_input.cpp +++ b/src/engine/sys/sdl_input.cpp @@ -1298,6 +1298,9 @@ void IN_FrameEnd() IN_Init =============== */ +#ifdef __APPLE__ +extern "C" void DisableAccentMenu(); +#endif void IN_Init( void *windowData ) { int appState; @@ -1328,6 +1331,13 @@ void IN_Init( void *windowData ) Cvar_SetValue( "com_unfocused", !( appState & SDL_WINDOW_INPUT_FOCUS ) ); Cvar_SetValue( "com_minimized", ( appState & SDL_WINDOW_MINIMIZED ) ); IN_InitJoystick(); + +#ifdef __APPLE__ + // We have to act after SDL does. Whoever has the last word wins! + // https://github.com/libsdl-org/SDL/commit/caf0348b26d02bc22ba9a0a908c83c43f8e4e6ad + DisableAccentMenu(); +#endif + Log::Debug( "------------------------------------" ); } From b9810e694a21a63074f51105c779b42e848ff1bb Mon Sep 17 00:00:00 2001 From: slipher Date: Fri, 15 Aug 2025 10:05:12 -0500 Subject: [PATCH 34/36] sdl3: fix r_displayIndex on Linux First of all, SDL always centers the window on all our platforms regardless of whether "centered" or "undefined" position is requested. It turns out that on Linux, requesting centering on display N makes it center on display N, while requesting any position on display N means center on unspecified display. So NUKE r_centerWindow and always request centering since not centering is never possible and this makes r_displayIndex be honored on Linux. --- src/engine/sys/sdl_glimp.cpp | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/engine/sys/sdl_glimp.cpp b/src/engine/sys/sdl_glimp.cpp index 33b5f59ca0..d76fa68028 100644 --- a/src/engine/sys/sdl_glimp.cpp +++ b/src/engine/sys/sdl_glimp.cpp @@ -472,7 +472,6 @@ enum class rserr_t }; cvar_t *r_allowResize; // make window resizable -cvar_t *r_centerWindow; cvar_t *r_displayIndex; cvar_t *r_sdlDriver; @@ -886,18 +885,8 @@ static bool GLimp_CreateWindow( bool fullscreen, bool bordered, const glConfigur SDL_free( displayIDs ); - int x, y; - if ( r_centerWindow->integer ) - { - // center window on specified display - x = SDL_WINDOWPOS_CENTERED_DISPLAY( displayID ); - y = SDL_WINDOWPOS_CENTERED_DISPLAY( displayID ); - } - else - { - x = SDL_WINDOWPOS_UNDEFINED_DISPLAY( displayID ); - y = SDL_WINDOWPOS_UNDEFINED_DISPLAY( displayID ); - } + int x = SDL_WINDOWPOS_CENTERED_DISPLAY( displayID ); + int y = SDL_WINDOWPOS_CENTERED_DISPLAY( displayID ); windowProperties = SDL_CreateProperties(); if ( !windowProperties ) @@ -2708,7 +2697,6 @@ bool GLimp_Init() r_sdlDriver = Cvar_Get( "r_sdlDriver", "", CVAR_ROM ); r_allowResize = Cvar_Get( "r_allowResize", "0", CVAR_LATCH ); - r_centerWindow = Cvar_Get( "r_centerWindow", "0", 0 ); r_displayIndex = Cvar_Get( "r_displayIndex", "0", 0 ); Cvar::Latch( workaround_glDriver_amd_adrenalin_disableBindlessTexture ); From c629b5e407a3af9658e20e4a0c81cdb488279bc7 Mon Sep 17 00:00:00 2001 From: slipher Date: Sat, 16 Aug 2025 22:58:37 +0200 Subject: [PATCH 35/36] external_deps: disable SDL3 deps on unwanted audio libs Fixes #1619. --- external_deps/build.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/external_deps/build.sh b/external_deps/build.sh index 6e53b868d3..569a69883f 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -478,7 +478,8 @@ build_sdl3() { cd "${dir_name}" cmake_build \ - -DSDL_TEST_LIBRARY=OFF + -DSDL_TEST_LIBRARY=OFF \ + -DSDL_AUDIO=OFF # Workaround for an SDL CMake bug, we need to provide # a bin/ directory even when nothing is used from it. @@ -718,7 +719,7 @@ build_openal() { "${download_only}" && return - local openal_cmake_args=(-DALSOFT_EXAMPLES=OFF) + local openal_cmake_args=(-DALSOFT_EXAMPLES=OFF -DALSOFT_BACKEND_SNDIO=OFF) case "${PLATFORM}" in *-i686-*|*-amd64-*) From ff61bd82e991c7e66c482cd6627525a25b0d05a5 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 1 Sep 2025 14:44:05 +0200 Subject: [PATCH 36/36] external_deps: remove the SDL workaround for missing bin/ folder --- external_deps/build.sh | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/external_deps/build.sh b/external_deps/build.sh index 569a69883f..dc0560f8bc 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -480,12 +480,6 @@ build_sdl3() { cmake_build \ -DSDL_TEST_LIBRARY=OFF \ -DSDL_AUDIO=OFF - - # Workaround for an SDL CMake bug, we need to provide - # a bin/ directory even when nothing is used from it. - mkdir -p "${PREFIX}/bin" - # We don't keep empty folders. - touch "${PREFIX}/bin/.keep" ;; esac } @@ -1204,7 +1198,7 @@ build_install() { rm -rf "${PKG_PREFIX}/def" rm -rf "${PKG_PREFIX}/share" rm -rf "${PKG_PREFIX}/lib/pkgconfig" - find "${PKG_PREFIX}/bin" -not -type d -not -name '*.dll' -not -name '.keep' -execdir rm -f -- {} \; + find "${PKG_PREFIX}/bin" -not -type d -not -name '*.dll' -not -execdir rm -f -- {} \; find "${PKG_PREFIX}/lib" -name '*.la' -execdir rm -f -- {} \; find "${PKG_PREFIX}/lib" -name '*.dll.a' -execdir bash -c 'rm -f -- "$(basename "{}" .dll.a).a"' \; find "${PKG_PREFIX}/lib" -name '*.dylib' -execdir bash -c 'rm -f -- "$(basename "{}" .dylib).a"' \;