diff --git a/devel/godot/Makefile b/devel/godot/Makefile index ae3631015b8f..abf7bb803de6 100644 --- a/devel/godot/Makefile +++ b/devel/godot/Makefile @@ -1,177 +1,177 @@ PORTNAME= godot -DISTVERSION= 4.4.1 +DISTVERSION= 4.6.1 DISTVERSIONSUFFIX= -stable -PORTREVISION?= 3 +PORTREVISION?= 0 CATEGORIES= devel games MAINTAINER= FreeBSD@Shaneware.biz COMMENT?= Game runtime engine WWW= https://godotengine.org/ LICENSE= CC-BY-3.0 MIT LICENSE_COMB= multi LICENSE_FILE_CC-BY-3.0= ${WRKSRC}/LOGO_LICENSE.txt LICENSE_FILE_MIT= ${WRKSRC}/LICENSE.txt BUILD_DEPENDS= yasm:devel/yasm LIB_DEPENDS= libbrotlicommon.so:archivers/brotli \ - libbrotlidec.so:archivers/brotli \ + libfontconfig.so:x11-fonts/fontconfig \ libfreetype.so:print/freetype2 \ libgraphite2.so:graphics/graphite2 \ libharfbuzz-icu.so:print/harfbuzz-icu \ libharfbuzz.so:print/harfbuzz \ + libmbedtls.so:security/mbedtls3 \ + libminiupnpc.so:net/miniupnpc \ libogg.so:audio/libogg \ + libpcre2-32.so:devel/pcre2 \ libpng.so:graphics/png \ + libRecast.so:graphics/recastnavigation \ libtheora.so:multimedia/libtheora \ - libtheoradec.so:multimedia/libtheora \ libvorbis.so:audio/libvorbis \ - libvorbisfile.so:audio/libvorbis \ libwebp.so:graphics/webp \ - libminiupnpc.so:net/miniupnpc \ - libopenxr_loader.so:graphics/openxr \ - libpcre2-32.so:devel/pcre2 \ - libRecast.so:graphics/recastnavigation \ libwslay_shared.so:www/wslay \ - libzstd.so:archivers/zstd \ - libfontconfig.so:x11-fonts/fontconfig + libzstd.so:archivers/zstd RUN_DEPENDS= xdg-open:devel/xdg-utils \ xdg-user-dir:devel/xdg-user-dirs \ xmessage:x11/xmessage -USES= compiler:c++17-lang cpe gl pkgconfig scons +USES= compiler:c++17-lang cpe gl pkgconfig scons sdl + CPE_VENDOR= godotengine USE_GITHUB= yes GH_ACCOUNT= godotengine USE_GL= gl glew glu - -MAKE_ARGS+= platform=linuxbsd \ - dbus=True \ - brotli=True \ - builtin_brotli=False \ - builtin_freetype=False \ - builtin_graphite=False \ - builtin_harfbuzz=False \ - builtin_libogg=False \ - builtin_libpng=False \ - builtin_libtheora=False \ - builtin_libvorbis=False \ - builtin_libwebp=False \ - builtin_miniupnpc=False \ - builtin_openxr=False \ - builtin_pcre2=False \ - builtin_recastnavigation=False \ - builtin_wslay=False \ - builtin_zlib=False \ - builtin_zstd=False \ - fontconfig=True \ - opengl3=True \ - use_sowrap=True \ - verbose=True \ - ${MAKE_ARGS_${CHOSEN_COMPILER_TYPE}} +USE_SDL= sdl3 + +# enabling builtin_openxr results in an uncaught exception during init +MAKE_ARGS+= platform=linuxbsd \ + dbus=True \ + brotli=True \ + builtin_brotli=False \ + builtin_freetype=False \ + builtin_graphite=False \ + builtin_harfbuzz=False \ + builtin_libogg=False \ + builtin_libpng=False \ + builtin_libtheora=False \ + builtin_libvorbis=False \ + builtin_libwebp=False \ + builtin_mbedtls=False \ + builtin_miniupnpc=False \ + builtin_pcre2=False \ + builtin_recastnavigation=False \ + builtin_sdl=False \ + builtin_wslay=False \ + builtin_zlib=False \ + builtin_zstd=False \ + fontconfig=True \ + opengl3=True \ + use_sowrap=True \ + verbose=True \ + disable_path_overrides=False \ + ${MAKE_ARGS_${CHOSEN_COMPILER_TYPE}} MAKE_ARGS_clang= use_llvm=True CXXFLAGS_i386= ${CXXFLAGS_i386_${CHOSEN_COMPILER_TYPE}} CXXFLAGS_i386_gcc= -march=i586 GODOTFILE= ${PORTNAME}${PKGNAMESUFFIX} PLIST_FILES= bin/${GODOTFILE} OPTIONS_DEFINE= EXAMPLES MOLD TEST TOOLS UDEV WAYLAND X11 OPTIONS_DEFAULT= ALSA UDEV WAYLAND X11 OPTIONS_GROUP= AUDIO OPTIONS_GROUP_AUDIO= ALSA PULSEAUDIO # Moved to devel/godot-tools OPTIONS_EXCLUDE?= EXAMPLES TOOLS AUDIO_DESC= Audio support MOLD_DESC= Use mold linker for faster compilation TOOLS_DESC= Include development tools (IDE) UDEV_DESC= Libudev support (Joystick) ALSA_LIB_DEPENDS= libasound.so:audio/alsa-lib ALSA_MAKE_ARGS= alsa=True ALSA_MAKE_ARGS_OFF= alsa=False -# master head at 6/3 - no branch made for 4.4 yet -EXAMPLES_GH_TUPLE= godotengine:godot-demo-projects:fdb2f50a2088:DEMOS +# master head at 20/2 - no branch made for 4.6 yet +EXAMPLES_GH_TUPLE= godotengine:godot-demo-projects:f228ea632391:DEMOS EXAMPLES_PORTEXAMPLES= * MOLD_BUILD_DEPENDS= mold:devel/mold MOLD_MAKE_ARGS= linker=mold MOLD_MAKE_ARGS_OFF= linker=lld PULSEAUDIO_LIB_DEPENDS= libpulse.so:audio/pulseaudio PULSEAUDIO_MAKE_ARGS= pulseaudio=True PULSEAUDIO_MAKE_ARGS_OFF= pulseaudio=False TEST_MAKE_ARGS= tests=True TOOLS_MAKE_ARGS= target=editor TOOLS_MAKE_ARGS_OFF= target=template_release TOOLS_DESKTOP_ENTRIES= "Godot Engine" "${COMMENT}" "${GODOTFILE}" \ "${GODOTFILE}" "Development;IDE;" "" TOOLS_PLIST_FILES= share/icons/hicolor/256x256/apps/${GODOTFILE}.png \ share/icons/hicolor/scalable/apps/${GODOTFILE}.svg UDEV_BUILD_DEPENDS= ${PREFIX}/include/linux/input.h:devel/evdev-proto UDEV_LIB_DEPENDS= libudev.so:devel/libudev-devd UDEV_MAKE_ARGS= udev=True UDEV_MAKE_ARGS_OFF= udev=False WAYLAND_BUILD_DEPENDS= wayland-protocols>0:graphics/wayland-protocols WAYLAND_LIB_DEPENDS= libwayland-client.so:graphics/wayland \ libxkbcommon.so:x11/libxkbcommon WAYLAND_MAKE_ARGS= wayland=True libdecor=True WAYLAND_MAKE_ARGS_OFF= wayland=False X11_USES= xorg X11_USE= XORG=x11,xcursor,xext,xi,xinerama,xrandr,xrender X11_MAKE_ARGS= x11=True X11_MAKE_ARGS_OFF= x11=False .ifmake makesum # Always include optional distfiles .MAKEFLAGS: WITH="${OPTIONS_DEFINE}" OPTIONS_EXCLUDE= .endif .include .if ${ARCH} == powerpc || ${ARCH:Mriscv64*} MAKE_ARGS+= module_embree_enabled=no \ module_raycast_enabled=no \ module_webm_enabled=no .endif post-patch: @${REINPLACE_CMD} -e 's|custom_build|${OPSYS}_Ports_build|' \ ${WRKSRC}/methods.py - @${REINPLACE_CMD} -e 's|/usr/include/recastnavigation|${LOCALBASE}/include/recastnavigation|' \ - ${WRKSRC}/platform/linuxbsd/detect.py # The official godot binary name reflects options used to compile # We just want a simple name matching the portname # This gives us bin/godot for runtime and bin/godot-tools for the IDE do-install: @${RM} ${WRKSRC}/bin/*.debugsymbols cd ${WRKSRC}/bin && ${INSTALL_PROGRAM} godot.linuxbsd* \ ${STAGEDIR}/${PREFIX}/bin/${GODOTFILE} do-install-EXAMPLES-on: (cd ${WRKSRC_DEMOS} && ${COPYTREE_SHARE} "${PORTEXAMPLES}" \ ${STAGEDIR}${EXAMPLESDIR}) do-install-TOOLS-on: @${MKDIR} ${STAGEDIR}${PREFIX}/share/icons/hicolor/256x256/apps \ ${STAGEDIR}${PREFIX}/share/icons/hicolor/scalable/apps ${INSTALL_DATA} ${WRKSRC}/icon.png \ ${STAGEDIR}${PREFIX}/share/icons/hicolor/256x256/apps/${GODOTFILE}.png ${INSTALL_DATA} ${WRKSRC}/icon.svg \ ${STAGEDIR}${PREFIX}/share/icons/hicolor/scalable/apps/${GODOTFILE}.svg .if ${PORT_OPTIONS:MTEST} do-test: ${MKDIR} ~/.cache/godot cd ${TEST_WRKSRC} && bin/godot.linuxbsd* --verbose --test .endif .include diff --git a/devel/godot/distinfo b/devel/godot/distinfo index fd408ab1b9a8..7f0ae7c99e85 100644 --- a/devel/godot/distinfo +++ b/devel/godot/distinfo @@ -1,5 +1,5 @@ -TIMESTAMP = 1744162984 -SHA256 (godotengine-godot-4.4.1-stable_GH0.tar.gz) = a486c523494e155b6912a607b5813577f8f39285f8ad43ac76cb9141edad9888 -SIZE (godotengine-godot-4.4.1-stable_GH0.tar.gz) = 55229702 -SHA256 (godotengine-godot-demo-projects-fdb2f50a2088_GH0.tar.gz) = 96faa3844742c9dc6ebc5354df5817c738855b9234931d7057d08ac3c20281f7 -SIZE (godotengine-godot-demo-projects-fdb2f50a2088_GH0.tar.gz) = 215650115 +TIMESTAMP = 1771988193 +SHA256 (godotengine-godot-4.6.1-stable_GH0.tar.gz) = f5d887cda2589fd2995b1cf7e74fe1ec54220f56d7fd6729a8a0865d794fb287 +SIZE (godotengine-godot-4.6.1-stable_GH0.tar.gz) = 66026623 +SHA256 (godotengine-godot-demo-projects-f228ea632391_GH0.tar.gz) = cc5f71e1e1522b612ccf900bcedf53d5280e10766a6d62a564a74de1e041be29 +SIZE (godotengine-godot-demo-projects-f228ea632391_GH0.tar.gz) = 244558016 diff --git a/devel/godot/files/patch-drivers_alsa_audio__driver__alsa.cpp b/devel/godot/files/patch-drivers_alsa_audio__driver__alsa.cpp new file mode 100644 index 000000000000..d02213a1d98d --- /dev/null +++ b/devel/godot/files/patch-drivers_alsa_audio__driver__alsa.cpp @@ -0,0 +1,11 @@ +--- drivers/alsa/audio_driver_alsa.cpp.orig 2024-04-14 15:55:55 UTC ++++ drivers/alsa/audio_driver_alsa.cpp +@@ -232,7 +232,7 @@ void AudioDriverALSA::thread_func(void *p_udata) { + ad->lock(); + ad->start_counting_ticks(); + } else { +- wrote = snd_pcm_recover(ad->pcm_handle, wrote, 0); ++ wrote = snd_pcm_recover(ad->pcm_handle, wrote, 1); // silence stdout + if (wrote < 0) { + ERR_PRINT("ALSA: Failed and can't recover: " + String(snd_strerror(wrote))); + ad->active.clear(); diff --git a/devel/godot/files/patch-drivers_sdl_SCsub b/devel/godot/files/patch-drivers_sdl_SCsub new file mode 100644 index 000000000000..3db25b424517 --- /dev/null +++ b/devel/godot/files/patch-drivers_sdl_SCsub @@ -0,0 +1,34 @@ +--- drivers/sdl/SCsub.orig 2025-10-13 19:05:40 UTC ++++ drivers/sdl/SCsub +@@ -1,5 +1,6 @@ from misc.utility.scons_hints import * + #!/usr/bin/env python + from misc.utility.scons_hints import * ++import sys + + Import("env") + +@@ -120,7 +121,15 @@ if env["builtin_sdl"]: + + if env["platform"] == "linuxbsd": + # TODO: Check support for BSD systems. +- env_sdl.Append(CPPDEFINES=["SDL_PLATFORM_LINUX"]) ++ if sys.platform.startswith("linux"): ++ env_sdl.Append(CPPDEFINES=["SDL_PLATFORM_LINUX"]) ++ elif sys.platform.startswith("freebsd") or sys.platform.startswith("dragonfly"): ++ env_sdl.Append(CPPDEFINES=["SDL_PLATFORM_FREEBSD"]) ++ elif sys.platform.startswith("openbsd"): ++ env_sdl.Append(CPPDEFINES=["SDL_PLATFORM_OPENBSD"]) ++ elif sys.platform.startswith("netbsd"): ++ env_sdl.Append(CPPDEFINES=["SDL_PLATFORM_NETBSD"]) ++ + thirdparty_sources += [ + "core/linux/SDL_dbus.c", + "core/linux/SDL_evdev.c", +@@ -132,6 +141,7 @@ if env["builtin_sdl"]: + "core/unix/SDL_poll.c", + "haptic/linux/SDL_syshaptic.c", + "joystick/linux/SDL_sysjoystick.c", ++ "joystick/bsd/SDL_bsdjoystick.c", + "loadso/dlopen/SDL_sysloadso.c", + "thread/pthread/SDL_syscond.c", + "thread/pthread/SDL_sysmutex.c", diff --git a/devel/godot/files/patch-drivers_sdl_SDL__build__config__private.h b/devel/godot/files/patch-drivers_sdl_SDL__build__config__private.h new file mode 100644 index 000000000000..9821a10d2440 --- /dev/null +++ b/devel/godot/files/patch-drivers_sdl_SDL__build__config__private.h @@ -0,0 +1,92 @@ +--- drivers/sdl/SDL_build_config_private.h.orig 2026-02-25 14:00:27 UTC ++++ drivers/sdl/SDL_build_config_private.h +@@ -75,26 +75,14 @@ + #define SDL_SENSOR_WINDOWS 1 + + // Linux defines +-#elif defined(SDL_PLATFORM_LINUX) ++#elif defined(SDL_PLATFORM_LINUX) || defined(SDL_PLATFORM_FREEBSD) || defined(SDL_PLATFORM_OPENBSD) || defined(SDL_PLATFORM_NETBSD) + +-#define SDL_PLATFORM_PRIVATE_NAME "Linux" + #define SDL_PLATFORM_UNIX 1 + + #define HAVE_STDIO_H 1 + #define HAVE_LIBC 1 +-#define HAVE_LINUX_INPUT_H 1 + #define HAVE_POLL 1 + +-#ifdef __linux__ +-#define HAVE_INOTIFY 1 +-#define HAVE_INOTIFY_INIT1 1 +-// Don't add these defines, for some reason they mess with C#'s ability +-// to use environment variables (see GH-109024) +-//#define HAVE_GETENV 1 +-//#define HAVE_SETENV 1 +-//#define HAVE_UNSETENV 1 +-#endif +- + #ifdef DBUS_ENABLED + #define HAVE_DBUS_DBUS_H 1 + #define SDL_USE_LIBDBUS 1 +@@ -105,17 +93,57 @@ + #define HAVE_LIBUDEV_H 1 + #define SDL_USE_LIBUDEV + #ifdef SOWRAP_ENABLED +-#define SDL_UDEV_DYNAMIC "libudev.so.1" ++#define SDL_UDEV_DYNAMIC "libudev.so.0" + #endif + #endif + + #define SDL_LOADSO_DLOPEN 1 +-#define SDL_HAPTIC_LINUX 1 + #define SDL_TIMER_UNIX 1 ++#define SDL_THREAD_PTHREAD 1 ++ ++#ifdef SDL_PLATFORM_LINUX ++#define SDL_PLATFORM_PRIVATE_NAME "Linux" ++ ++#define HAVE_LINUX_INPUT_H 1 ++#define SDL_HAPTIC_LINUX 1 + #define SDL_JOYSTICK_LINUX 1 +-#define SDL_JOYSTICK_HIDAPI 1 + #define SDL_INPUT_LINUXEV 1 +-#define SDL_THREAD_PTHREAD 1 ++ ++#define HAVE_INOTIFY 1 ++#define HAVE_INOTIFY_INIT1 1 ++ ++// Don't add these defines, for some reason they mess with C#'s ability ++// to use environment variables (see GH-109024) ++//#define HAVE_GETENV 1 ++//#define HAVE_SETENV 1 ++//#define HAVE_UNSETENV 1 ++ ++#else ++ ++#ifdef SDL_PLATFORM_FREEBSD ++#define SDL_PLATFORM_PRIVATE_NAME "FreeBSD" ++//#define HAVE_USBHID_H 1 // this needs more work ++#define HAVE_LINUX_INPUT_H 1 ++#define SDL_HAPTIC_LINUX 1 ++#define SDL_JOYSTICK_LINUX 1 ++#define SDL_INPUT_LINUXEV 1 ++#elif defined(SDL_PLATFORM_OPENBSD) ++#define SDL_PLATFORM_PRIVATE_NAME "OpenBSD" ++#define HAVE_USBHID_H 1 ++#define USBHID_NEW 1 ++#define USBHID_UCR_DATA 1 ++#elif defined(SDL_PLATFORM_NETBSD) ++#define SDL_PLATFORM_PRIVATE_NAME "NetBSD" ++#define HAVE_USBHID_H 1 ++#define USBHID_NEW 1 ++#define USBHID_UCR_DATA 1 ++#endif ++ ++#define SDL_HAPTIC_DISABLED 1 ++#define SDL_JOYSTICK_USBHID 1 ++ ++#endif ++ + + // MacOS defines + #elif defined(SDL_PLATFORM_MACOS) diff --git a/devel/godot/files/patch-platform__methods.py b/devel/godot/files/patch-platform__methods.py index daa296c2438a..4af720d58bd1 100644 --- a/devel/godot/files/patch-platform__methods.py +++ b/devel/godot/files/patch-platform__methods.py @@ -1,21 +1,20 @@ ---- platform_methods.py.orig 2025-03-25 23:11:16 UTC +--- platform_methods.py.orig 2026-01-25 23:11:41 UTC +++ platform_methods.py -@@ -28,6 +28,9 @@ architecture_aliases = { +@@ -29,13 +29,16 @@ architecture_aliases = { "rv": "rv64", "riscv": "rv64", "riscv64": "rv64", + "powerpc64le": "ppc64", + "powerpc64": "ppc64", + "powerpc": "ppc32", - "ppcle": "ppc32", - "ppc": "ppc32", "ppc64le": "ppc64", -@@ -36,7 +39,7 @@ def detect_arch(): + "loong64": "loongarch64", + } def detect_arch(): - host_machine = platform.machine().lower() + host_machine = platform.processor().lower() if host_machine in architectures: return host_machine elif host_machine in architecture_aliases.keys(): diff --git a/devel/godot/files/patch-platform_linuxbsd_detect.py b/devel/godot/files/patch-platform_linuxbsd_detect.py index 0deebc9387b2..bf95c86c74be 100644 --- a/devel/godot/files/patch-platform_linuxbsd_detect.py +++ b/devel/godot/files/patch-platform_linuxbsd_detect.py @@ -1,11 +1,72 @@ ---- platform/linuxbsd/detect.py.orig 2025-03-25 23:11:16 UTC +--- platform/linuxbsd/detect.py.orig 2025-10-13 19:05:40 UTC +++ platform/linuxbsd/detect.py -@@ -373,7 +373,7 @@ def configure(env: "SConsEnvironment"): +@@ -382,7 +382,7 @@ def configure(env: "SConsEnvironment"): else: env.Append(CPPDEFINES=["XKB_ENABLED"]) - if platform.system() == "Linux": -+ if platform.system() in ["Linux","FreeBSD"]: - env.Append(CPPDEFINES=["JOYDEV_ENABLED"]) ++ if platform.system() in ["Linux", "FreeBSD"]: if env["udev"]: if not env["use_sowrap"]: + if os.system("pkg-config --exists libudev") == 0: # 0 means found +@@ -395,13 +395,17 @@ def configure(env: "SConsEnvironment"): + env.Append(CPPDEFINES=["UDEV_ENABLED"]) + else: + env["udev"] = False # Linux specific +- ++ + if env["sdl"]: + if env["builtin_sdl"]: + env.Append(CPPDEFINES=["SDL_ENABLED"]) ++ if platform.system() in ["FreeBSD", "OpenBSD", "NetBSD"]: ++ env["LINKCOM"] += " -l:libusbhid.a" + elif os.system("pkg-config --exists sdl3") == 0: # 0 means found + env.ParseConfig("pkg-config sdl3 --cflags --libs") + env.Append(CPPDEFINES=["SDL_ENABLED"]) ++ if platform.system() in ["FreeBSD", "OpenBSD", "NetBSD"]: ++ env.Append(LIBS=["usbhid"]) + else: + print_warning( + "SDL3 development libraries not found, and `builtin_sdl` was explicitly disabled. Disabling SDL input driver support." +@@ -484,7 +488,9 @@ def configure(env: "SConsEnvironment"): + env.Append(CPPDEFINES=["LIBDECOR_ENABLED"]) + + env.Append(CPPDEFINES=["WAYLAND_ENABLED"]) +- env.Append(LIBS=["rt"]) # Needed by glibc, used by _allocate_shm_file ++ # FreeBSD and OpenBSD keep rt functionality in libc ++ if platform.system() in ["Linux", "NetBSD"]: ++ env.Append(LIBS=["rt"]) # Needed by glibc, used by _allocate_shm_file + + if env["accesskit"]: + if env["accesskit_sdk_path"] != "": +@@ -517,7 +523,7 @@ def configure(env: "SConsEnvironment"): + + env.Append(LIBS=["pthread"]) + +- if platform.system() == "Linux": ++ if platform.system() in ["Linux", "FreeBSD"]: + env.Append(LIBS=["dl"]) + + if platform.libc_ver()[0] != "glibc": +@@ -536,9 +542,17 @@ def configure(env: "SConsEnvironment"): + + # Link those statically for portability + if env["use_static_cpp"]: +- env.Append(LINKFLAGS=["-static-libgcc", "-static-libstdc++"]) +- if env["use_llvm"] and platform.system() != "FreeBSD": +- env["LINKCOM"] = env["LINKCOM"] + " -l:libatomic.a" ++ # TODO Test NetBSD clang, guessing that it also does not support -static-libstdc++? Does its libc++ have other deps? ++ if env["use_llvm"] and platform.system() in ["FreeBSD", "OpenBSD", "NetBSD"]: ++ env.Append(LINKFLAGS=["-nostdlib++"]) ++ env["LINKCOM"] += " -l:libc++.a" ++ if platform.system() == "OpenBSD": ++ env["LINKCOM"] += " -l:libc++abi.a" ++ else: ++ env.Append(LINKFLAGS=["-static-libgcc", "-static-libstdc++"]) ++ ++ if env["use_llvm"] and platform.system() not in ["FreeBSD", "OpenBSD", "NetBSD"]: ++ env["LINKCOM"] += " -l:libatomic.a" + else: +- if env["use_llvm"] and platform.system() != "FreeBSD": ++ if env["use_llvm"] and platform.system() not in ["FreeBSD", "OpenBSD", "NetBSD"]: + env.Append(LIBS=["atomic"]) diff --git a/devel/godot/files/patch-platform_linuxbsd_libudev-so__wrap.c b/devel/godot/files/patch-platform_linuxbsd_libudev-so__wrap.c deleted file mode 100644 index 6f50b34142d9..000000000000 --- a/devel/godot/files/patch-platform_linuxbsd_libudev-so__wrap.c +++ /dev/null @@ -1,11 +0,0 @@ ---- platform/linuxbsd/libudev-so_wrap.c.orig 2025-02-19 15:17:47 UTC -+++ platform/linuxbsd/libudev-so_wrap.c -@@ -281,7 +281,7 @@ - int initialize_libudev(int verbose) { - void *handle; - char *error; -- handle = dlopen("libudev.so.1", RTLD_LAZY); -+ handle = dlopen("libudev.so.0", RTLD_LAZY); - if (!handle) { - if (verbose) { - fprintf(stderr, "%s\n", dlerror()); diff --git a/devel/godot/files/patch-platform_linuxbsd_platform__config.h b/devel/godot/files/patch-platform_linuxbsd_platform__config.h new file mode 100644 index 000000000000..09278d411fb0 --- /dev/null +++ b/devel/godot/files/patch-platform_linuxbsd_platform__config.h @@ -0,0 +1,31 @@ +--- platform/linuxbsd/platform_config.h.orig 2025-10-13 19:05:40 UTC ++++ platform/linuxbsd/platform_config.h +@@ -30,18 +30,22 @@ + + #pragma once + ++// alloca + #ifdef __linux__ + #include ++#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) ++#ifdef __cplusplus ++#include ++#else ++#include + #endif ++#endif + +-#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +-#include // alloca ++#if defined(__FreeBSD__) || defined(__OpenBSD__) + // FreeBSD and OpenBSD use pthread_set_name_np, while other platforms, + // include NetBSD, use pthread_setname_np. NetBSD's version however requires + // a different format, we handle this directly in thread_posix. +-#ifdef __NetBSD__ +-#define PTHREAD_NETBSD_SET_NAME +-#else + #define PTHREAD_BSD_SET_NAME +-#endif ++#elif defined(__NetBSD__) ++#define PTHREAD_NETBSD_SET_NAME + #endif diff --git a/devel/godot/files/patch-platform_linuxbsd_wayland_wayland__embedder.cpp b/devel/godot/files/patch-platform_linuxbsd_wayland_wayland__embedder.cpp new file mode 100644 index 000000000000..77628d425520 --- /dev/null +++ b/devel/godot/files/patch-platform_linuxbsd_wayland_wayland__embedder.cpp @@ -0,0 +1,65 @@ +--- platform/linuxbsd/wayland/wayland_embedder.cpp.orig 2026-01-25 12:41:41 UTC ++++ platform/linuxbsd/wayland/wayland_embedder.cpp +@@ -38,6 +38,22 @@ + + #ifdef __FreeBSD__ + #include ++#include ++#include ++#include ++#include ++ ++/** if CMSG_ALIGN is not defined on this platform, a workaround */ ++#ifndef CMSG_ALIGN ++# ifdef __CMSG_ALIGN ++# define CMSG_ALIGN(n) __CMSG_ALIGN(n) ++# elif defined(CMSG_DATA_ALIGN) ++# define CMSG_ALIGN _CMSG_DATA_ALIGN ++# else ++# define CMSG_ALIGN(len) (((len)+sizeof(long)-1) & ~(sizeof(long)-1)) ++# endif ++#endif ++ + #else + // Assume Linux. + #include +@@ -2869,15 +2885,27 @@ void WaylandEmbedder::handle_fd(int p_fd, int p_revent + int new_fd = accept(proxy_socket, nullptr, nullptr); + ERR_FAIL_COND_MSG(new_fd == -1, "Failed to accept client."); + ++#if defined(__FreeBSD__) ++ struct xucred cred = {}; ++#else + struct ucred cred = {}; ++#endif + socklen_t cred_size = sizeof cred; ++#if defined(__FreeBSD__) ++ getsockopt(new_fd, SOL_LOCAL, LOCAL_PEERCRED, &cred, &cred_size); ++#else + getsockopt(new_fd, SOL_SOCKET, SO_PEERCRED, &cred, &cred_size); ++#endif + + Client &client = clients.insert_new(new_fd, {})->value; + + client.embedder = this; + client.socket = new_fd; ++#if defined(__FreeBSD__) ++ client.pid = cred.cr_pid; ++#else + client.pid = cred.pid; ++#endif + + client.global_ids[DISPLAY_ID] = Client::GlobalIdInfo(DISPLAY_ID, nullptr); + client.local_ids[DISPLAY_ID] = DISPLAY_ID; +@@ -2900,7 +2928,11 @@ void WaylandEmbedder::handle_fd(int p_fd, int p_revent + main_client->new_fake_object(new_local_id, &godot_embedded_client_interface, 1, eclient_data); + + // godot_embedding_compositor::client(nu) ++#if defined(__FreeBSD__) ++ send_wayland_message(main_client->socket, local_id, 0, { new_local_id, (uint32_t)cred.cr_pid }); ++#else + send_wayland_message(main_client->socket, local_id, 0, { new_local_id, (uint32_t)cred.pid }); ++#endif + } + } + diff --git a/devel/godot/files/patch-platform_linuxbsd_wayland_wayland__thread.cpp b/devel/godot/files/patch-platform_linuxbsd_wayland_wayland__thread.cpp new file mode 100644 index 000000000000..9222403d3c82 --- /dev/null +++ b/devel/godot/files/patch-platform_linuxbsd_wayland_wayland__thread.cpp @@ -0,0 +1,65 @@ +--- platform/linuxbsd/wayland/wayland_thread.cpp.orig 2025-10-13 19:05:40 UTC ++++ platform/linuxbsd/wayland/wayland_thread.cpp +@@ -95,7 +95,7 @@ Vector WaylandThread::_read_fd(int fd) { + break; + } + +- DEBUG_LOG_WAYLAND_THREAD(vformat("Read chunk of %d bytes.", last_bytes_read)); ++ DEBUG_LOG_WAYLAND_THREAD(vformat("Read chunk of %d bytes.", (uint64_t)last_bytes_read)); + + bytes_read += last_bytes_read; + +@@ -1197,7 +1197,7 @@ void WaylandThread::_wl_surface_on_enter(void *data, s + WindowState *ws = (WindowState *)data; + ERR_FAIL_NULL(ws); + +- DEBUG_LOG_WAYLAND_THREAD(vformat("Window entered output %x.", (size_t)wl_output)); ++ DEBUG_LOG_WAYLAND_THREAD(vformat("Window entered output %x.", (uint64_t)wl_output)); + + ws->wl_outputs.insert(wl_output); + +@@ -1248,7 +1248,7 @@ void WaylandThread::_wl_surface_on_leave(void *data, s + + ws->wl_outputs.erase(wl_output); + +- DEBUG_LOG_WAYLAND_THREAD(vformat("Window left output %x.\n", (size_t)wl_output)); ++ DEBUG_LOG_WAYLAND_THREAD(vformat("Window left output %x.\n", (uint64_t)wl_output)); + } + + // TODO: Add support to this event. +@@ -1310,7 +1310,7 @@ void WaylandThread::_wl_output_on_done(void *data, str + + ss->wayland_thread->_update_scale(ss->data.scale); + +- DEBUG_LOG_WAYLAND_THREAD(vformat("Output %x done.", (size_t)wl_output)); ++ DEBUG_LOG_WAYLAND_THREAD(vformat("Output %x done.", (uint64_t)wl_output)); + } + + void WaylandThread::_wl_output_on_scale(void *data, struct wl_output *wl_output, int32_t factor) { +@@ -1319,7 +1319,7 @@ void WaylandThread::_wl_output_on_scale(void *data, st + + ss->pending_data.scale = factor; + +- DEBUG_LOG_WAYLAND_THREAD(vformat("Output %x scale %d", (size_t)wl_output, factor)); ++ DEBUG_LOG_WAYLAND_THREAD(vformat("Output %x scale %d", (uint64_t)wl_output, factor)); + } + + void WaylandThread::_wl_output_on_name(void *data, struct wl_output *wl_output, const char *name) { +@@ -2509,7 +2509,7 @@ void WaylandThread::_wl_data_source_on_send(void *data + } + + if (written_bytes > 0) { +- DEBUG_LOG_WAYLAND_THREAD(vformat("Clipboard: sent %d bytes.", written_bytes)); ++ DEBUG_LOG_WAYLAND_THREAD(vformat("Clipboard: sent %d bytes.", (uint64_t)written_bytes)); + } else if (written_bytes == 0) { + DEBUG_LOG_WAYLAND_THREAD("Clipboard: no bytes sent."); + } else { +@@ -2697,7 +2697,7 @@ void WaylandThread::_wp_primary_selection_source_on_se + } + + if (written_bytes > 0) { +- DEBUG_LOG_WAYLAND_THREAD(vformat("Clipboard: sent %d bytes.", written_bytes)); ++ DEBUG_LOG_WAYLAND_THREAD(vformat("Clipboard: sent %d bytes.", (uint64_t)written_bytes)); + } else if (written_bytes == 0) { + DEBUG_LOG_WAYLAND_THREAD("Clipboard: no bytes sent."); + } else { diff --git a/devel/godot/files/patch-thirdparty_jolt__physics_Jolt_Core_Core.h b/devel/godot/files/patch-thirdparty_jolt__physics_Jolt_Core_Core.h index 41a7d11c20b0..cc435c7b4c70 100644 --- a/devel/godot/files/patch-thirdparty_jolt__physics_Jolt_Core_Core.h +++ b/devel/godot/files/patch-thirdparty_jolt__physics_Jolt_Core_Core.h @@ -1,11 +1,11 @@ ---- thirdparty/jolt_physics/Jolt/Core/Core.h.orig 2025-08-13 15:24:56 UTC +--- thirdparty/jolt_physics/Jolt/Core/Core.h.orig 2025-10-13 19:05:40 UTC +++ thirdparty/jolt_physics/Jolt/Core/Core.h -@@ -215,7 +215,7 @@ +@@ -219,7 +219,7 @@ #define JPH_CPU_BIG_ENDIAN #endif #define JPH_VECTOR_ALIGNMENT 16 - #define JPH_DVECTOR_ALIGNMENT 8 + #define JPH_DVECTOR_ALIGNMENT 16 #elif defined(__loongarch__) // LoongArch CPU architecture #define JPH_CPU_LOONGARCH diff --git a/devel/godot/files/patch-thirdparty_linuxbsd__headers_udev_libudev.h b/devel/godot/files/patch-thirdparty_linuxbsd__headers_udev_libudev.h index 5720c06187c2..25f688956637 100644 --- a/devel/godot/files/patch-thirdparty_linuxbsd__headers_udev_libudev.h +++ b/devel/godot/files/patch-thirdparty_linuxbsd__headers_udev_libudev.h @@ -1,11 +1,11 @@ ---- thirdparty/linuxbsd_headers/udev/libudev.h.orig 2025-02-15 07:16:26 UTC +--- thirdparty/linuxbsd_headers/udev/libudev.h.orig 2025-10-13 19:05:40 UTC +++ thirdparty/linuxbsd_headers/udev/libudev.h @@ -22,7 +22,7 @@ #define _LIBUDEV_H_ #include -#include +// #include #include #ifdef __cplusplus diff --git a/devel/godot/files/patch-thirdparty_sdl_joystick_bsd_SDL__bsdjoystick.c b/devel/godot/files/patch-thirdparty_sdl_joystick_bsd_SDL__bsdjoystick.c new file mode 100644 index 000000000000..6c24d1c685f4 --- /dev/null +++ b/devel/godot/files/patch-thirdparty_sdl_joystick_bsd_SDL__bsdjoystick.c @@ -0,0 +1,872 @@ +--- thirdparty/sdl/joystick/bsd/SDL_bsdjoystick.c.orig 2026-01-03 09:26:31 UTC ++++ thirdparty/sdl/joystick/bsd/SDL_bsdjoystick.c +@@ -0,0 +1,869 @@ ++/* ++ Simple DirectMedia Layer ++ Copyright (C) 1997-2025 Sam Lantinga ++ ++ This software is provided 'as-is', without any express or implied ++ warranty. In no event will the authors be held liable for any damages ++ arising from the use of this software. ++ ++ Permission is granted to anyone to use this software for any purpose, ++ including commercial applications, and to alter it and redistribute it ++ freely, subject to the following restrictions: ++ ++ 1. The origin of this software must not be misrepresented; you must not ++ claim that you wrote the original software. If you use this software ++ in a product, an acknowledgment in the product documentation would be ++ appreciated but is not required. ++ 2. Altered source versions must be plainly marked as such, and must not be ++ misrepresented as being the original software. ++ 3. This notice may not be removed or altered from any source distribution. ++*/ ++#include "SDL_internal.h" ++ ++#ifdef SDL_JOYSTICK_USBHID ++ ++/* ++ * Joystick driver for the uhid(4) / ujoy(4) interface found in OpenBSD, ++ * NetBSD and FreeBSD. ++ * ++ * Maintainer: ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++#ifndef __FreeBSD_kernel_version ++#define __FreeBSD_kernel_version __FreeBSD_version ++#endif ++ ++#ifdef HAVE_USB_H ++#include ++#endif ++#ifdef __DragonFly__ ++#include ++#include ++#else ++#include ++#include ++#endif ++ ++#ifdef HAVE_USBHID_H ++#include ++#elif defined(HAVE_LIBUSB_H) ++#include ++#elif defined(HAVE_LIBUSBHID_H) ++#include ++#endif ++ ++#if defined(SDL_PLATFORM_FREEBSD) ++#include ++#if __FreeBSD_kernel_version > 800063 ++#include ++#elif defined(__DragonFly__) ++#include ++#endif ++#include ++#include ++#endif ++ ++#ifdef SDL_HAVE_MACHINE_JOYSTICK_H ++#include ++#endif ++ ++#include "../SDL_sysjoystick.h" ++#include "../SDL_joystick_c.h" ++#include "../hidapi/SDL_hidapijoystick_c.h" ++ ++#if defined(SDL_PLATFORM_FREEBSD) || defined(SDL_HAVE_MACHINE_JOYSTICK_H) || defined(__FreeBSD_kernel__) || defined(__DragonFly_) ++#define SUPPORT_JOY_GAMEPORT ++#endif ++ ++#define MAX_UHID_JOYS 64 ++#define MAX_JOY_JOYS 2 ++#define MAX_JOYS (MAX_UHID_JOYS + MAX_JOY_JOYS) ++ ++#ifdef SDL_PLATFORM_OPENBSD ++ ++#define HUG_DPAD_UP 0x90 ++#define HUG_DPAD_DOWN 0x91 ++#define HUG_DPAD_RIGHT 0x92 ++#define HUG_DPAD_LEFT 0x93 ++ ++#define HAT_UP 0x01 ++#define HAT_RIGHT 0x02 ++#define HAT_DOWN 0x04 ++#define HAT_LEFT 0x08 ++ ++#endif ++ ++struct report ++{ ++#if defined(SDL_PLATFORM_FREEBSD) && (__FreeBSD_kernel_version > 900000) || \ ++ defined(__DragonFly__) ++ void *buf; // Buffer ++#elif defined(SDL_PLATFORM_FREEBSD) && (__FreeBSD_kernel_version > 800063) ++ struct usb_gen_descriptor *buf; // Buffer ++#else ++ struct usb_ctl_report *buf; // Buffer ++#endif ++ size_t size; // Buffer size ++ int rid; // Report ID ++ enum ++ { ++ SREPORT_UNINIT, ++ SREPORT_CLEAN, ++ SREPORT_DIRTY ++ } status; ++}; ++ ++static struct ++{ ++ int uhid_report; ++ hid_kind_t kind; ++ const char *name; ++} const repinfo[] = { ++ { UHID_INPUT_REPORT, hid_input, "input" }, ++ { UHID_OUTPUT_REPORT, hid_output, "output" }, ++ { UHID_FEATURE_REPORT, hid_feature, "feature" } ++}; ++ ++enum ++{ ++ REPORT_INPUT = 0, ++ REPORT_OUTPUT = 1, ++ REPORT_FEATURE = 2 ++}; ++ ++enum ++{ ++ JOYAXE_X, ++ JOYAXE_Y, ++ JOYAXE_Z, ++ JOYAXE_SLIDER, ++ JOYAXE_WHEEL, ++ JOYAXE_RX, ++ JOYAXE_RY, ++ JOYAXE_RZ, ++ JOYAXE_count ++}; ++ ++struct joystick_hwdata ++{ ++ int fd; ++ enum ++ { ++ BSDJOY_UHID, // uhid(4) ++ BSDJOY_JOY // joy(4) ++ } type; ++ ++ int naxes; ++ int nbuttons; ++ int nhats; ++ struct report_desc *repdesc; ++ struct report inreport; ++ int axis_map[JOYAXE_count]; /* map present JOYAXE_* to 0,1,.. */ ++}; ++ ++// A linked list of available joysticks ++typedef struct SDL_joylist_item ++{ ++ SDL_JoystickID device_instance; ++ char *path; // "/dev/uhid0" or whatever ++ char *name; // "SideWinder 3D Pro" or whatever ++ SDL_GUID guid; ++ dev_t devnum; ++ struct SDL_joylist_item *next; ++} SDL_joylist_item; ++ ++static SDL_joylist_item *SDL_joylist = NULL; ++static SDL_joylist_item *SDL_joylist_tail = NULL; ++static int numjoysticks = 0; ++ ++static bool report_alloc(struct report *, struct report_desc *, int); ++static void report_free(struct report *); ++ ++#if defined(USBHID_UCR_DATA) || (defined(__FreeBSD_kernel__) && __FreeBSD_kernel_version <= 800063) ++#define REP_BUF_DATA(rep) ((rep)->buf->ucr_data) ++#elif (defined(SDL_PLATFORM_FREEBSD) && (__FreeBSD_kernel_version > 900000)) || \ ++ defined(__DragonFly__) ++#define REP_BUF_DATA(rep) ((rep)->buf) ++#elif (defined(SDL_PLATFORM_FREEBSD) && (__FreeBSD_kernel_version > 800063)) ++#define REP_BUF_DATA(rep) ((rep)->buf->ugd_data) ++#else ++#define REP_BUF_DATA(rep) ((rep)->buf->data) ++#endif ++ ++static int usage_to_joyaxe(int usage) ++{ ++ int joyaxe; ++ switch (usage) { ++ case HUG_X: ++ joyaxe = JOYAXE_X; ++ break; ++ case HUG_Y: ++ joyaxe = JOYAXE_Y; ++ break; ++ case HUG_Z: ++ joyaxe = JOYAXE_Z; ++ break; ++ case HUG_SLIDER: ++ joyaxe = JOYAXE_SLIDER; ++ break; ++ case HUG_WHEEL: ++ joyaxe = JOYAXE_WHEEL; ++ break; ++ case HUG_RX: ++ joyaxe = JOYAXE_RX; ++ break; ++ case HUG_RY: ++ joyaxe = JOYAXE_RY; ++ break; ++ case HUG_RZ: ++ joyaxe = JOYAXE_RZ; ++ break; ++ default: ++ joyaxe = -1; ++ } ++ return joyaxe; ++} ++ ++static void FreeJoylistItem(SDL_joylist_item *item) ++{ ++ SDL_free(item->path); ++ SDL_free(item->name); ++ SDL_free(item); ++} ++ ++static void FreeHwData(struct joystick_hwdata *hw) ++{ ++ if (hw->type == BSDJOY_UHID) { ++ report_free(&hw->inreport); ++ ++ if (hw->repdesc) { ++ hid_dispose_report_desc(hw->repdesc); ++ } ++ } ++ close(hw->fd); ++ SDL_free(hw); ++} ++ ++static struct joystick_hwdata *CreateHwData(const char *path) ++{ ++ struct joystick_hwdata *hw; ++ struct hid_item hitem; ++ struct hid_data *hdata; ++ struct report *rep = NULL; ++ int fd; ++ int i; ++ ++ fd = open(path, O_RDONLY | O_CLOEXEC); ++ if (fd == -1) { ++ SDL_SetError("%s: %s", path, strerror(errno)); ++ return NULL; ++ } ++ ++ hw = (struct joystick_hwdata *) ++ SDL_calloc(1, sizeof(struct joystick_hwdata)); ++ if (!hw) { ++ close(fd); ++ return NULL; ++ } ++ hw->fd = fd; ++ ++#ifdef SUPPORT_JOY_GAMEPORT ++ if (SDL_strncmp(path, "/dev/joy", 8) == 0) { ++ hw->type = BSDJOY_JOY; ++ hw->naxes = 2; ++ hw->nbuttons = 2; ++ } else ++#endif ++ { ++ hw->type = BSDJOY_UHID; ++ { ++ int ax; ++ for (ax = 0; ax < JOYAXE_count; ax++) { ++ hw->axis_map[ax] = -1; ++ } ++ } ++ hw->repdesc = hid_get_report_desc(fd); ++ if (!hw->repdesc) { ++ SDL_SetError("%s: USB_GET_REPORT_DESC: %s", path, ++ strerror(errno)); ++ goto usberr; ++ } ++ rep = &hw->inreport; ++#if defined(SDL_PLATFORM_FREEBSD) && (__FreeBSD_kernel_version > 800063) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) ++ rep->rid = hid_get_report_id(fd); ++ if (rep->rid < 0) { ++#else ++ if (ioctl(fd, USB_GET_REPORT_ID, &rep->rid) < 0) { ++#endif ++ rep->rid = -1; // XXX ++ } ++ if (!report_alloc(rep, hw->repdesc, REPORT_INPUT)) { ++ goto usberr; ++ } ++ if (rep->size <= 0) { ++ SDL_SetError("%s: Input report descriptor has invalid length", ++ path); ++ goto usberr; ++ } ++#if defined(USBHID_NEW) || (defined(SDL_PLATFORM_FREEBSD) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) ++ hdata = hid_start_parse(hw->repdesc, 1 << hid_input, rep->rid); ++#else ++ hdata = hid_start_parse(hw->repdesc, 1 << hid_input); ++#endif ++ if (!hdata) { ++ SDL_SetError("%s: Cannot start HID parser", path); ++ goto usberr; ++ } ++ for (i = 0; i < JOYAXE_count; i++) { ++ hw->axis_map[i] = -1; ++ } ++ ++ while (hid_get_item(hdata, &hitem) > 0) { ++ switch (hitem.kind) { ++ case hid_input: ++ switch (HID_PAGE(hitem.usage)) { ++ case HUP_GENERIC_DESKTOP: ++ { ++ int usage = HID_USAGE(hitem.usage); ++ int joyaxe = usage_to_joyaxe(usage); ++ if (joyaxe >= 0) { ++ hw->axis_map[joyaxe] = 1; ++ } else if (usage == HUG_HAT_SWITCH ++#ifdef SDL_PLATFORM_OPENBSD ++ || usage == HUG_DPAD_UP ++#endif ++ ) { ++ hw->nhats++; ++ } ++ break; ++ } ++ case HUP_BUTTON: ++ { ++ int usage = HID_USAGE(hitem.usage); ++ if (usage > hw->nbuttons) { ++ hw->nbuttons = usage; ++ } ++ } break; ++ default: ++ break; ++ } ++ break; ++ default: ++ break; ++ } ++ } ++ hid_end_parse(hdata); ++ for (i = 0; i < JOYAXE_count; i++) { ++ if (hw->axis_map[i] > 0) { ++ hw->axis_map[i] = hw->naxes++; ++ } ++ } ++ ++ if (hw->naxes == 0 && hw->nbuttons == 0 && hw->nhats == 0) { ++ SDL_SetError("%s: Not a joystick, ignoring", path); ++ goto usberr; ++ } ++ } ++ ++ // The poll blocks the event thread. ++ fcntl(fd, F_SETFL, O_NONBLOCK); ++#ifdef SDL_PLATFORM_NETBSD ++ // Flush pending events ++ if (rep) { ++ while (read(fd, REP_BUF_DATA(rep), rep->size) == rep->size) ++ ; ++ } ++#endif ++ ++ return hw; ++ ++usberr: ++ FreeHwData(hw); ++ return NULL; ++} ++ ++static bool MaybeAddDevice(const char *path) ++{ ++ struct stat sb; ++ char *name = NULL; ++ SDL_GUID guid; ++ SDL_joylist_item *item; ++ struct joystick_hwdata *hw; ++ ++ if (!path) { ++ return false; ++ } ++ ++ if (stat(path, &sb) == -1) { ++ return false; ++ } ++ ++ // Check to make sure it's not already in list. ++ for (item = SDL_joylist; item; item = item->next) { ++ if (sb.st_rdev == item->devnum) { ++ return false; // already have this one ++ } ++ } ++ ++ hw = CreateHwData(path); ++ if (!hw) { ++ return false; ++ } ++ ++ if (hw->type == BSDJOY_JOY) { ++ name = SDL_strdup("Gameport joystick"); ++ guid = SDL_CreateJoystickGUIDForName(name); ++ } else { ++#ifdef USB_GET_DEVICEINFO ++ struct usb_device_info di; ++ if (ioctl(hw->fd, USB_GET_DEVICEINFO, &di) != -1) { ++ name = SDL_CreateJoystickName(di.udi_vendorNo, di.udi_productNo, di.udi_vendor, di.udi_product); ++ guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_USB, di.udi_vendorNo, di.udi_productNo, di.udi_releaseNo, di.udi_vendor, di.udi_product, 0, 0); ++ ++ if (SDL_ShouldIgnoreJoystick(di.udi_vendorNo, di.udi_productNo, di.udi_releaseNo, name) || ++ SDL_JoystickHandledByAnotherDriver(&SDL_BSD_JoystickDriver, di.udi_vendorNo, di.udi_productNo, di.udi_releaseNo, name)) { ++ SDL_free(name); ++ FreeHwData(hw); ++ return false; ++ } ++ } ++#endif // USB_GET_DEVICEINFO ++ } ++ if (!name) { ++ name = SDL_strdup(path); ++ guid = SDL_CreateJoystickGUIDForName(name); ++ } ++ FreeHwData(hw); ++ ++ item = (SDL_joylist_item *)SDL_calloc(1, sizeof(SDL_joylist_item)); ++ if (!item) { ++ SDL_free(name); ++ return false; ++ } ++ ++ item->devnum = sb.st_rdev; ++ item->path = SDL_strdup(path); ++ item->name = name; ++ item->guid = guid; ++ ++ if ((!item->path) || (!item->name)) { ++ FreeJoylistItem(item); ++ return false; ++ } ++ ++ item->device_instance = SDL_GetNextObjectID(); ++ if (!SDL_joylist_tail) { ++ SDL_joylist = SDL_joylist_tail = item; ++ } else { ++ SDL_joylist_tail->next = item; ++ SDL_joylist_tail = item; ++ } ++ ++ // Need to increment the joystick count before we post the event ++ ++numjoysticks; ++ ++ SDL_PrivateJoystickAdded(item->device_instance); ++ ++ return true; ++} ++ ++static bool BSD_JoystickInit(void) ++{ ++ char s[16]; ++ int i; ++ ++ for (i = 0; i < MAX_UHID_JOYS; i++) { ++#if defined(SDL_PLATFORM_OPENBSD) && (OpenBSD >= 202105) ++ SDL_snprintf(s, SDL_arraysize(s), "/dev/ujoy/%d", i); ++#else ++ SDL_snprintf(s, SDL_arraysize(s), "/dev/uhid%d", i); ++#endif ++ MaybeAddDevice(s); ++ } ++#ifdef SUPPORT_JOY_GAMEPORT ++ for (i = 0; i < MAX_JOY_JOYS; i++) { ++ SDL_snprintf(s, SDL_arraysize(s), "/dev/joy%d", i); ++ MaybeAddDevice(s); ++ } ++#endif // SUPPORT_JOY_GAMEPORT ++ ++ // Read the default USB HID usage table. ++ hid_init(NULL); ++ ++ return true; ++} ++ ++static int BSD_JoystickGetCount(void) ++{ ++ return numjoysticks; ++} ++ ++static void BSD_JoystickDetect(void) ++{ ++} ++ ++static bool BSD_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) ++{ ++ // We don't override any other drivers ++ return false; ++} ++ ++static SDL_joylist_item *GetJoystickByDevIndex(int device_index) ++{ ++ SDL_joylist_item *item = SDL_joylist; ++ ++ if ((device_index < 0) || (device_index >= numjoysticks)) { ++ return NULL; ++ } ++ ++ while (device_index > 0) { ++ SDL_assert(item != NULL); ++ device_index--; ++ item = item->next; ++ } ++ ++ return item; ++} ++ ++static const char *BSD_JoystickGetDeviceName(int device_index) ++{ ++ return GetJoystickByDevIndex(device_index)->name; ++} ++ ++static const char *BSD_JoystickGetDevicePath(int device_index) ++{ ++ return GetJoystickByDevIndex(device_index)->path; ++} ++ ++static int BSD_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index) ++{ ++ return -1; ++} ++ ++static int BSD_JoystickGetDevicePlayerIndex(int device_index) ++{ ++ return -1; ++} ++ ++static void BSD_JoystickSetDevicePlayerIndex(int device_index, int player_index) ++{ ++} ++ ++static SDL_GUID BSD_JoystickGetDeviceGUID(int device_index) ++{ ++ return GetJoystickByDevIndex(device_index)->guid; ++} ++ ++// Function to perform the mapping from device index to the instance id for this index ++static SDL_JoystickID BSD_JoystickGetDeviceInstanceID(int device_index) ++{ ++ return GetJoystickByDevIndex(device_index)->device_instance; ++} ++ ++static unsigned hatval_to_sdl(Sint32 hatval) ++{ ++ static const unsigned hat_dir_map[8] = { ++ SDL_HAT_UP, SDL_HAT_RIGHTUP, SDL_HAT_RIGHT, SDL_HAT_RIGHTDOWN, ++ SDL_HAT_DOWN, SDL_HAT_LEFTDOWN, SDL_HAT_LEFT, SDL_HAT_LEFTUP ++ }; ++ unsigned result; ++ if ((hatval & 7) == hatval) ++ result = hat_dir_map[hatval]; ++ else ++ result = SDL_HAT_CENTERED; ++ return result; ++} ++ ++static bool BSD_JoystickOpen(SDL_Joystick *joy, int device_index) ++{ ++ SDL_joylist_item *item = GetJoystickByDevIndex(device_index); ++ struct joystick_hwdata *hw; ++ ++ if (!item) { ++ return SDL_SetError("No such device"); ++ } ++ ++ hw = CreateHwData(item->path); ++ if (!hw) { ++ return false; ++ } ++ ++ joy->hwdata = hw; ++ joy->naxes = hw->naxes; ++ joy->nbuttons = hw->nbuttons; ++ joy->nhats = hw->nhats; ++ ++ return true; ++} ++ ++static void BSD_JoystickUpdate(SDL_Joystick *joy) ++{ ++ struct hid_item hitem; ++ struct hid_data *hdata; ++ struct report *rep; ++ int nbutton, naxe = -1; ++ Sint32 v; ++#ifdef SDL_PLATFORM_OPENBSD ++ Sint32 dpad[4] = { 0, 0, 0, 0 }; ++#endif ++ Uint64 timestamp = SDL_GetTicksNS(); ++ ++#ifdef SUPPORT_JOY_GAMEPORT ++ struct joystick gameport; ++ static int x, y, xmin = 0xffff, ymin = 0xffff, xmax = 0, ymax = 0; ++ ++ if (joy->hwdata->type == BSDJOY_JOY) { ++ while (read(joy->hwdata->fd, &gameport, sizeof(gameport)) == sizeof(gameport)) { ++ if (SDL_abs(x - gameport.x) > 8) { ++ x = gameport.x; ++ if (x < xmin) { ++ xmin = x; ++ } ++ if (x > xmax) { ++ xmax = x; ++ } ++ if (xmin == xmax) { ++ xmin--; ++ xmax++; ++ } ++ v = (((SDL_JOYSTICK_AXIS_MAX - SDL_JOYSTICK_AXIS_MIN) * ((Sint32)x - xmin)) / (xmax - xmin)) + SDL_JOYSTICK_AXIS_MIN; ++ SDL_SendJoystickAxis(timestamp, joy, 0, v); ++ } ++ if (SDL_abs(y - gameport.y) > 8) { ++ y = gameport.y; ++ if (y < ymin) { ++ ymin = y; ++ } ++ if (y > ymax) { ++ ymax = y; ++ } ++ if (ymin == ymax) { ++ ymin--; ++ ymax++; ++ } ++ v = (((SDL_JOYSTICK_AXIS_MAX - SDL_JOYSTICK_AXIS_MIN) * ((Sint32)y - ymin)) / (ymax - ymin)) + SDL_JOYSTICK_AXIS_MIN; ++ SDL_SendJoystickAxis(timestamp, joy, 1, v); ++ } ++ SDL_SendJoystickButton(timestamp, joy, 0, (gameport.b1 != 0)); ++ SDL_SendJoystickButton(timestamp, joy, 1, (gameport.b2 != 0)); ++ } ++ return; ++ } ++#endif // SUPPORT_JOY_GAMEPORT ++ ++ rep = &joy->hwdata->inreport; ++ ++ while (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) == rep->size) { ++#if defined(USBHID_NEW) || (defined(SDL_PLATFORM_FREEBSD) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) ++ hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input, rep->rid); ++#else ++ hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input); ++#endif ++ if (!hdata) { ++ // fprintf(stderr, "%s: Cannot start HID parser\n", joy->hwdata->path); ++ continue; ++ } ++ ++ while (hid_get_item(hdata, &hitem) > 0) { ++ switch (hitem.kind) { ++ case hid_input: ++ switch (HID_PAGE(hitem.usage)) { ++ case HUP_GENERIC_DESKTOP: ++ { ++ int usage = HID_USAGE(hitem.usage); ++ int joyaxe = usage_to_joyaxe(usage); ++ if (joyaxe >= 0) { ++ naxe = joy->hwdata->axis_map[joyaxe]; ++ // scaleaxe ++ v = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); ++ v = (((SDL_JOYSTICK_AXIS_MAX - SDL_JOYSTICK_AXIS_MIN) * (v - hitem.logical_minimum)) / (hitem.logical_maximum - hitem.logical_minimum)) + SDL_JOYSTICK_AXIS_MIN; ++ SDL_SendJoystickAxis(timestamp, joy, naxe, v); ++ } else if (usage == HUG_HAT_SWITCH) { ++ v = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); ++ SDL_SendJoystickHat(timestamp, joy, 0, ++ hatval_to_sdl(v) - ++ hitem.logical_minimum); ++ } ++#ifdef SDL_PLATFORM_OPENBSD ++ /* here D-pad directions are reported like separate buttons. ++ * calculate the SDL hat value from the 4 separate values. ++ */ ++ switch (usage) { ++ case HUG_DPAD_UP: ++ dpad[0] = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); ++ break; ++ case HUG_DPAD_DOWN: ++ dpad[1] = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); ++ break; ++ case HUG_DPAD_RIGHT: ++ dpad[2] = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); ++ break; ++ case HUG_DPAD_LEFT: ++ dpad[3] = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); ++ break; ++ //default: ++ // no-op ++ } ++ SDL_SendJoystickHat(timestamp, joy, 0, (dpad[0] * HAT_UP) | ++ (dpad[1] * HAT_DOWN) | ++ (dpad[2] * HAT_RIGHT) | ++ (dpad[3] * HAT_LEFT) ); ++#endif ++ break; ++ } ++ case HUP_BUTTON: ++ v = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); ++ nbutton = HID_USAGE(hitem.usage) - 1; // SDL buttons are zero-based ++ SDL_SendJoystickButton(timestamp, joy, nbutton, (v != 0)); ++ break; ++ default: ++ continue; ++ } ++ break; ++ default: ++ break; ++ } ++ } ++ hid_end_parse(hdata); ++ } ++} ++ ++// Function to close a joystick after use ++static void BSD_JoystickClose(SDL_Joystick *joy) ++{ ++ if (joy->hwdata) { ++ FreeHwData(joy->hwdata); ++ joy->hwdata = NULL; ++ } ++} ++ ++static void BSD_JoystickQuit(void) ++{ ++ SDL_joylist_item *item = NULL; ++ SDL_joylist_item *next = NULL; ++ ++ for (item = SDL_joylist; item; item = next) { ++ next = item->next; ++ FreeJoylistItem(item); ++ } ++ ++ SDL_joylist = SDL_joylist_tail = NULL; ++ ++ numjoysticks = 0; ++} ++ ++static bool report_alloc(struct report *r, struct report_desc *rd, int repind) ++{ ++ int len; ++ ++#ifdef __DragonFly__ ++ len = hid_report_size(rd, repinfo[repind].kind, r->rid); ++#elif defined(SDL_PLATFORM_FREEBSD) ++#if (__FreeBSD_kernel_version >= 460000) || defined(__FreeBSD_kernel__) ++#if (__FreeBSD_kernel_version <= 500111) ++ len = hid_report_size(rd, r->rid, repinfo[repind].kind); ++#else ++ len = hid_report_size(rd, repinfo[repind].kind, r->rid); ++#endif ++#else ++ len = hid_report_size(rd, repinfo[repind].kind, &r->rid); ++#endif ++#else ++#ifdef USBHID_NEW ++ len = hid_report_size(rd, repinfo[repind].kind, r->rid); ++#else ++ len = hid_report_size(rd, repinfo[repind].kind, &r->rid); ++#endif ++#endif ++ ++ if (len < 0) { ++ return SDL_SetError("Negative HID report size"); ++ } ++ r->size = len; ++ ++ if (r->size > 0) { ++#if defined(SDL_PLATFORM_FREEBSD) && (__FreeBSD_kernel_version > 900000) || defined(__DragonFly__) ++ r->buf = SDL_malloc(r->size); ++#else ++ r->buf = SDL_malloc(sizeof(*r->buf) - sizeof(REP_BUF_DATA(r)) + ++ r->size); ++#endif ++ if (!r->buf) { ++ return false; ++ } ++ } else { ++ r->buf = NULL; ++ } ++ ++ r->status = SREPORT_CLEAN; ++ return true; ++} ++ ++static void report_free(struct report *r) ++{ ++ SDL_free(r->buf); ++ r->status = SREPORT_UNINIT; ++} ++ ++static bool BSD_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) ++{ ++ return SDL_Unsupported(); ++} ++ ++static bool BSD_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) ++{ ++ return SDL_Unsupported(); ++} ++ ++static bool BSD_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) ++{ ++ return false; ++} ++ ++static bool BSD_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) ++{ ++ return SDL_Unsupported(); ++} ++ ++static bool BSD_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) ++{ ++ return SDL_Unsupported(); ++} ++ ++static bool BSD_JoystickSetSensorsEnabled(SDL_Joystick *joystick, bool enabled) ++{ ++ return SDL_Unsupported(); ++} ++ ++SDL_JoystickDriver SDL_BSD_JoystickDriver = { ++ BSD_JoystickInit, ++ BSD_JoystickGetCount, ++ BSD_JoystickDetect, ++ BSD_JoystickIsDevicePresent, ++ BSD_JoystickGetDeviceName, ++ BSD_JoystickGetDevicePath, ++ BSD_JoystickGetDeviceSteamVirtualGamepadSlot, ++ BSD_JoystickGetDevicePlayerIndex, ++ BSD_JoystickSetDevicePlayerIndex, ++ BSD_JoystickGetDeviceGUID, ++ BSD_JoystickGetDeviceInstanceID, ++ BSD_JoystickOpen, ++ BSD_JoystickRumble, ++ BSD_JoystickRumbleTriggers, ++ BSD_JoystickSetLED, ++ BSD_JoystickSendEffect, ++ BSD_JoystickSetSensorsEnabled, ++ BSD_JoystickUpdate, ++ BSD_JoystickClose, ++ BSD_JoystickQuit, ++ BSD_JoystickGetGamepadMapping ++}; ++ ++#endif // SDL_JOYSTICK_USBHID