diff --git a/.github/workflows/android_builds.yml b/.github/workflows/android_builds.yml index 74f73e98789..a94ca149c97 100644 --- a/.github/workflows/android_builds.yml +++ b/.github/workflows/android_builds.yml @@ -18,7 +18,7 @@ jobs: name: Template (target=template_release) steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Java 11 uses: actions/setup-java@v3 diff --git a/.github/workflows/godot_cpp_test.yml b/.github/workflows/godot_cpp_test.yml index ea428e2b561..136b9f7a32b 100644 --- a/.github/workflows/godot_cpp_test.yml +++ b/.github/workflows/godot_cpp_test.yml @@ -16,14 +16,14 @@ jobs: runs-on: "ubuntu-20.04" name: "Build and test Godot CPP" steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup python and scons uses: ./.github/actions/godot-deps # Checkout godot-cpp - name: Checkout godot-cpp - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: godotengine/godot-cpp ref: ${{ env.GODOT_BASE_BRANCH }} diff --git a/.github/workflows/ios_builds.yml b/.github/workflows/ios_builds.yml index c1ed4009cad..8d7e5cb056b 100644 --- a/.github/workflows/ios_builds.yml +++ b/.github/workflows/ios_builds.yml @@ -18,7 +18,7 @@ jobs: name: Template (target=template_release) steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Godot build cache uses: ./.github/actions/godot-cache diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index cb6f833a59b..048e7eaf517 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -74,7 +74,7 @@ jobs: artifact: true steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 # Need newer mesa for lavapipe to work properly. - name: Linux dependencies for tests @@ -100,7 +100,7 @@ jobs: uses: ./.github/actions/godot-deps - name: Set up .NET Sdk - uses: actions/setup-dotnet@v2 + uses: actions/setup-dotnet@v3 if: ${{ matrix.build-mono }} with: dotnet-version: '6.0.x' @@ -119,7 +119,7 @@ jobs: - name: Generate C# glue if: ${{ matrix.build-mono }} run: | - ${{ matrix.bin }} --headless --generate-mono-glue ./modules/mono/glue || true + ${{ matrix.bin }} --headless --generate-mono-glue ./modules/mono/glue - name: Build .NET solutions if: ${{ matrix.build-mono }} @@ -165,7 +165,7 @@ jobs: - name: Check for GDExtension compatibility if: ${{ matrix.api-compat }} run: | - ./misc/scripts/validate_extension_api.sh "${{ matrix.bin }}" || true # don't fail the CI for now + ./misc/scripts/validate_extension_api.sh "${{ matrix.bin }}" # Download and run the test project - name: Test Godot project diff --git a/.github/workflows/macos_builds.yml b/.github/workflows/macos_builds.yml index f2f659ef525..7d96a3b6dfe 100644 --- a/.github/workflows/macos_builds.yml +++ b/.github/workflows/macos_builds.yml @@ -33,7 +33,7 @@ jobs: sconsflags: debug_symbols=no steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Godot build cache uses: ./.github/actions/godot-cache diff --git a/.github/workflows/static_checks.yml b/.github/workflows/static_checks.yml index 6133780688a..fba556bb6cd 100644 --- a/.github/workflows/static_checks.yml +++ b/.github/workflows/static_checks.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 2 diff --git a/.github/workflows/web_builds.yml b/.github/workflows/web_builds.yml index 61f836189f7..57f1822f558 100644 --- a/.github/workflows/web_builds.yml +++ b/.github/workflows/web_builds.yml @@ -7,7 +7,7 @@ env: # Used for the cache key. Add version suffix to force clean build. GODOT_BASE_BRANCH: '4.1' SCONSFLAGS: verbose=yes warnings=extra werror=yes debug_symbols=no - EM_VERSION: 3.1.18 + EM_VERSION: 3.1.45 EM_CACHE_FOLDER: "emsdk-cache" concurrency: @@ -16,11 +16,11 @@ concurrency: jobs: web-template: - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-22.04" name: Template (target=template_release) steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Emscripten latest uses: mymindstorm/setup-emsdk@v12 diff --git a/.github/workflows/windows_builds.yml b/.github/workflows/windows_builds.yml index 20bc6010d1c..b11e10ca080 100644 --- a/.github/workflows/windows_builds.yml +++ b/.github/workflows/windows_builds.yml @@ -38,7 +38,7 @@ jobs: sconsflags: debug_symbols=no steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Godot build cache uses: ./.github/actions/godot-cache diff --git a/CHANGELOG.md b/CHANGELOG.md index df7b6421f90..e53f750df5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,10 +8,214 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added +#### Core + +- Add check to ensure registered classes are declared ([GH-81020](https://github.com/godotengine/godot/pull/81020)). + +#### Rendering + +- Add motion vector support for GPU 3D Particles ([GH-80688](https://github.com/godotengine/godot/pull/80688)). + +#### Shaders + +- Allow more hint types for uniform arrays ([GH-79100](https://github.com/godotengine/godot/pull/79100)). +- Add autocomplete for filter/repeat hints on uniform arrays ([GH-79402](https://github.com/godotengine/godot/pull/79402)). + ### Changed +#### 3D + +- Change property hint range for camera attributes exposure multiplier ([GH-79138](https://github.com/godotengine/godot/pull/79138)). + +#### Buildsystem + +- Disable C++ exception handling (off by default in 4.1) ([GH-80612](https://github.com/godotengine/godot/pull/80612)). +- libpng: Enable intrinsics on x86/SSE2, ppc64/VSX, and all arm/NEON ([GH-78325](https://github.com/godotengine/godot/pull/78325)). +- Linux: Allow unbundling OpenXR ([GH-73443](https://github.com/godotengine/godot/pull/73443)). +- MSVC: Pass build options configuration to Visual Studio projects ([GH-79238](https://github.com/godotengine/godot/pull/79238)). +- MSVC: Make incremental linking optional ([GH-80482](https://github.com/godotengine/godot/pull/80482), [GH-81144](https://github.com/godotengine/godot/pull/81144)). +- MSVC: Enable `/WX` on LINKFLAGS for MSVC with `werror=yes` ([GH-80711](https://github.com/godotengine/godot/pull/80711)). + +#### C#/.NET + +- Hide hostfxr not found error ([GH-81690](https://github.com/godotengine/godot/pull/81690)). + +#### Editor + +- Don't use splash minimum display time in editor ([GH-79388](https://github.com/godotengine/godot/pull/79388)). +- Automatically add path to built-in scripts ([GH-79920](https://github.com/godotengine/godot/pull/79920)). +- Uncollapse favorites by default in the editor FileSystem dock ([GH-79971](https://github.com/godotengine/godot/pull/79971)). +- Use `ui_text_submit` instead of `ui_accept` to confirm and close text prompts ([GH-81189](https://github.com/godotengine/godot/pull/81189)). +- Make editor camera speed indicator use `m/s` and `m` ([GH-81810](https://github.com/godotengine/godot/pull/81810)). + +#### GUI + +- Enable transparent background for GUI tooltips ([GH-81669](https://github.com/godotengine/godot/pull/81669)). + +#### Input + +- Prevent double input events on gamepad when running through steam input ([GH-76045](https://github.com/godotengine/godot/pull/76045)). +- Ensure `joy_connection_changed` is emitted on the main thread ([GH-80432](https://github.com/godotengine/godot/pull/80432)). +- Android: Set `echo` property for the physical keyboard events ([GH-79089](https://github.com/godotengine/godot/pull/79089)). + +#### Networking + +- Web: Always return -1 as body length in HTTPClientWeb ([GH-79846](https://github.com/godotengine/godot/pull/79846)). + +#### Porting + +- X11: Do not fail DisplayServer init if non-essential extensions are missing ([GH-80240](https://github.com/godotengine/godot/pull/80240)). + +#### Rendering + +- Enable depth writes during shadow pass and depth pass, disable during color pass ([GH-80070](https://github.com/godotengine/godot/pull/80070)). +- Remove GPU readback from `NoiseTexture3D.get_format()` ([GH-80407](https://github.com/godotengine/godot/pull/80407)). +- Clamp Volumetric Fog Length property to prevent rendering issues ([GH-80485](https://github.com/godotengine/godot/pull/80485)). +- Propagate error correctly when max texture size for lightmaps is too small ([GH-81543](https://github.com/godotengine/godot/pull/81543)). +- GLES3: Reset anisotropic filtering when changing texture filtering mode ([GH-79568](https://github.com/godotengine/godot/pull/79568)). +- GLES3: Don't call `glTexParameter*` for invalid filter and repeat modes ([GH-79685](https://github.com/godotengine/godot/pull/79685)). + +#### Thirdparty + +- FreeType updated to version 2.13.2. +- ICU4C updated to version 73.2. +- libpng updated to version 1.6.40. +- libwebp updated to version 1.3.1. +- mbedtls updated to version version 2.28.4. +- miniupnpc updated to version 2.2.5. +- openxr updated to version 1.0.28. +- tinyexr updated to version 1.0.7. + ### Fixed +#### 2D + +- Fix Camera2D crash when edited scene root is null ([GH-79645](https://github.com/godotengine/godot/pull/79645)). +- Fix `CanvasModulate` logic for modulating the canvas ([GH-79747](https://github.com/godotengine/godot/pull/79747)). + +#### 3D + +- Fix VoxelGI saving VoxelGIData as a built-in file, despite being prompted to save it to an external file ([GH-78772](https://github.com/godotengine/godot/pull/78772)). +- Fix Curve3D baking up vectors for nontrivial curves ([GH-81885](https://github.com/godotengine/godot/pull/81885)). + +#### Animation + +- Fix `Animation::subtract_variant` for affine transforms ([GH-79279](https://github.com/godotengine/godot/pull/79279)). +- Fix `AnimationNodeTransition` with negative time scale ([GH-79403](https://github.com/godotengine/godot/pull/79403)). +- Remove animation tracks with correct indices ([GH-81651](https://github.com/godotengine/godot/pull/81651)). + +#### Audio + +- Fix audio stream generators getting freed accidentally ([GH-81508](https://github.com/godotengine/godot/pull/81508)). + +#### Buildsystem + +- Fix GCC `-Wmaybe-uninitialized` warnings ([GH-80615](https://github.com/godotengine/godot/pull/80615)). +- Web: Workaround Emscripten 3.1.42+ LTO regression ([GH-81340](https://github.com/godotengine/godot/pull/81340)). + +#### C#/.NET + +- Fix deserialization of delegates that are 0-parameter overloads ([GH-78877](https://github.com/godotengine/godot/pull/78877)). +- Add missing `useModelFront` parameter to GodotSharp Basis and Transform ([GH-79082](https://github.com/godotengine/godot/pull/79082)). +- Fix double unregistration on dispose of Array ([GH-81230](https://github.com/godotengine/godot/pull/81230)). + +#### Core + +- Fix range error for `Array.slice` ([GH-79103](https://github.com/godotengine/godot/pull/79103)). +- Fix byte to float color conversion in `DisplayServerWindows::screen_get_pixel` ([GH-79350](https://github.com/godotengine/godot/pull/79350)). +- Fix recursion level check for array stringification ([GH-79370](https://github.com/godotengine/godot/pull/79370)). +- Fix global transform validity for `Node2D` and `Control` ([GH-80105](https://github.com/godotengine/godot/pull/80105)). +- Fix recursion level check for `VariantWriter::write()` with objects ([GH-81123](https://github.com/godotengine/godot/pull/81123)). +- Fix string conversion for -0.0 float values ([GH-81328](https://github.com/godotengine/godot/pull/81328)). + +#### Editor + +- Fix history mismatch ([GH-78827](https://github.com/godotengine/godot/pull/78827)). +- Improve resolution of script type icons ([GH-79203](https://github.com/godotengine/godot/pull/79203), [GH-81336](https://github.com/godotengine/godot/pull/81336)). +- Fix arg count checks in `SceneDebugger` ([GH-79655](https://github.com/godotengine/godot/pull/79655)). +- Make the single window mode check more strict ([GH-79793](https://github.com/godotengine/godot/pull/79793)). +- Fix crash when using "Close All Tabs" ([GH-79917](https://github.com/godotengine/godot/pull/79917)). +- Fix a crash when plugin tries to call `make_mesh_previews` on enable ([GH-81121](https://github.com/godotengine/godot/pull/81121)). + +#### Export + +- Fix Windows console wrapper and icon being swapped ([GH-80357](https://github.com/godotengine/godot/pull/80357)). + +#### GDExtension + +- Fix version check for GDExtension ([GH-80591](https://github.com/godotengine/godot/pull/80591)). +- Fix overriding `_export_begin`, `_export_file` and `_export_end` from GDExtension ([GH-80999](https://github.com/godotengine/godot/pull/80999)). + +#### GDScript + +- Fix conflict between property and group names ([GH-78254](https://github.com/godotengine/godot/pull/78254)). +- Properly track extents of constants ([GH-79301](https://github.com/godotengine/godot/pull/79301)). +- Fix dumping of signal API parameters ([GH-81599](https://github.com/godotengine/godot/pull/81599)). + +#### GUI + +- Fix RichTextLabel character line and paragraph index getters ([GH-76759](https://github.com/godotengine/godot/pull/76759)). +- Fix text overlapping icon in `Tree` ([GH-78756](https://github.com/godotengine/godot/pull/78756)). +- Fix delay on tab resizing when (un)hovering tabs ([GH-78777](https://github.com/godotengine/godot/pull/78777)). +- Fix `Tree` performance regression by using cache ([GH-79325](https://github.com/godotengine/godot/pull/79325)). +- Fix Button clipping when internal margins exist ([GH-79455](https://github.com/godotengine/godot/pull/79455)). +- Make `OptionButton`` resize when disabling "Fit to Longest Item" ([GH-79494](https://github.com/godotengine/godot/pull/79494)). +- Fix `root_node_layout_direction` project setting being incorrectly exposed as a range ([GH-79611](https://github.com/godotengine/godot/pull/79611)). +- Fix `Button` text when the overrun behavior is other than "No Trimming" ([GH-80402](https://github.com/godotengine/godot/pull/80402)). +- Fix `CodeEdit` completion being very slow in certain cases ([GH-80472](https://github.com/godotengine/godot/pull/80472)). +- Fix crash when hiding subwindow during popup of new subwindow ([GH-80780](https://github.com/godotengine/godot/pull/80780)). +- RTL: Improve performance by using list iterators for item/paragraph removal ([GH-80857](https://github.com/godotengine/godot/pull/80857)). +- Fix setting TabContainer's `font_hovered_color` theme property ([GH-81040](https://github.com/godotengine/godot/pull/81040)). +- Fix ItemList not updating when icon scale changes ([GH-81268](https://github.com/godotengine/godot/pull/81268)). + +#### Import + +- Use image index instead of texture index for `source_images` ([GH-80314](https://github.com/godotengine/godot/pull/80314)). + +#### Navigation + +- Fix NavigationObstacle2D debug position ([GH-79392](https://github.com/godotengine/godot/pull/79392)). +- Make NavigationRegion3D baking NavMesh on the main thread not finish deferred ([GH-79465](https://github.com/godotengine/godot/pull/79465)). +- Fix NavMesh `map_update_id` returning 0 results in errors ([GH-80189](https://github.com/godotengine/godot/pull/80189)). + +#### Networking + +- Prevent crash when accessing `Node` Multiplayer from thread ([GH-79332](https://github.com/godotengine/godot/pull/79332)). +- ENet: Better handle truncated socket messages ([GH-79699](https://github.com/godotengine/godot/pull/79699)). +- ENet: Properly set transfer flags when using custom channels ([GH-80293](https://github.com/godotengine/godot/pull/80293)). + +#### Porting + +- macOS: Fix uncapped frame rate for windows in the non-active workspaces ([GH-79572](https://github.com/godotengine/godot/pull/79572)). +- Web: Fix file permissions for the web platform (affects every Unix-like platform) ([GH-79866](https://github.com/godotengine/godot/pull/79866)). +- Web: Fix `JavaScriptBridge.eval()` never returning PackedByteArray ([GH-81015](https://github.com/godotengine/godot/pull/81015)). + +#### Rendering + +- Fix crash when calling `get_video_adapter_*` in a thread ([GH-79528](https://github.com/godotengine/godot/pull/79528)). +- Unbind the framebuffer when updating meshes ([GH-79772](https://github.com/godotengine/godot/pull/79772)). +- Fix motion vectors being corrupted when using `precision=double` ([GH-80257](https://github.com/godotengine/godot/pull/80257)). +- Fix integer underflow when rounding up in VoxelGI ([GH-80356](https://github.com/godotengine/godot/pull/80356)). +- Improve handling of motion vectors for multimesh instances ([GH-80414](https://github.com/godotengine/godot/pull/80414)). +- Clear SDFGI textures when created ([GH-80889](https://github.com/godotengine/godot/pull/80889)). +- Fix integer value for `GL_MAX_UNIFORM_BLOCK_SIZE` overflowing ([GH-80909](https://github.com/godotengine/godot/pull/80909)). +- Add half-pixel offset to lightmapper rasterization ([GH-81872](https://github.com/godotengine/godot/pull/81872)). +- GLES3: Fix multimesh rendering when using colors or custom data ([GH-79660](https://github.com/godotengine/godot/pull/79660)). +- GLES3: Fix memory access error for `MultiMesh` ([GH-80788](https://github.com/godotengine/godot/pull/80788)). +- GLES3: Fix `glMapBufferRange` return null when `r_index + last_item_index > max_instance` ([GH-81036](https://github.com/godotengine/godot/pull/81036)). +- Vulkan: Fix texture update ([GH-80781](https://github.com/godotengine/godot/pull/80781)). +- Vulkan: Fix crash with many Omni/SpotLights, Decals or ReflectionProbes ([GH-80845](https://github.com/godotengine/godot/pull/80845)). + +#### Shaders + +- Fix shader type detection ([GH-79287](https://github.com/godotengine/godot/pull/79287)). +- Fix Shader and ShaderInclude resource loading ([GH-80705](https://github.com/godotengine/godot/pull/80705)). +- Fix empty shader resource loading ([GH-81300](https://github.com/godotengine/godot/pull/81300)). + +#### XR + +- Fix issue with accessing hand tracking without timing info ([GH-78817](https://github.com/godotengine/godot/pull/78817)). + ## [4.1.1] - 2023-07-17 diff --git a/SConstruct b/SConstruct index 22c9e18c081..791ff463039 100644 --- a/SConstruct +++ b/SConstruct @@ -193,6 +193,7 @@ opts.Add(BoolVariable("vulkan", "Enable the vulkan rendering driver", True)) opts.Add(BoolVariable("opengl3", "Enable the OpenGL/GLES3 rendering driver", True)) opts.Add(BoolVariable("openxr", "Enable the OpenXR driver", True)) opts.Add(BoolVariable("use_volk", "Use the volk library to load the Vulkan loader dynamically", True)) +opts.Add(BoolVariable("disable_exceptions", "Force disabling exception handling code", False)) opts.Add("custom_modules", "A list of comma-separated directory paths containing custom modules to build.", "") opts.Add(BoolVariable("custom_modules_recursive", "Detect custom modules recursively for each specified path.", True)) @@ -240,6 +241,7 @@ opts.Add(BoolVariable("builtin_libwebp", "Use the built-in libwebp library", Tru opts.Add(BoolVariable("builtin_wslay", "Use the built-in wslay library", True)) opts.Add(BoolVariable("builtin_mbedtls", "Use the built-in mbedTLS library", True)) opts.Add(BoolVariable("builtin_miniupnpc", "Use the built-in miniupnpc library", True)) +opts.Add(BoolVariable("builtin_openxr", "Use the built-in OpenXR library", True)) opts.Add(BoolVariable("builtin_pcre2", "Use the built-in PCRE2 library", True)) opts.Add(BoolVariable("builtin_pcre2_with_jit", "Use JIT compiler for the built-in PCRE2 library", True)) opts.Add(BoolVariable("builtin_recastnavigation", "Use the built-in Recast navigation library", True)) @@ -699,6 +701,16 @@ if selected_platform in platform_list: ) Exit(255) + # Disable exception handling. Godot doesn't use exceptions anywhere, and this + # saves around 20% of binary size and very significant build time (GH-80513). + if env["disable_exceptions"]: + if env.msvc: + env.Append(CPPDEFINES=[("_HAS_EXCEPTIONS", 0)]) + else: + env.Append(CCFLAGS=["-fno-exceptions"]) + elif env.msvc: + env.Append(CCFLAGS=["/EHsc"]) + # Configure compiler warnings if env.msvc: # MSVC if env["warnings"] == "no": @@ -728,11 +740,9 @@ if selected_platform in platform_list: ] ) - # Set exception handling model to avoid warnings caused by Windows system headers. - env.Append(CCFLAGS=["/EHsc"]) - if env["werror"]: env.Append(CCFLAGS=["/WX"]) + env.Append(LINKFLAGS=["/WX"]) else: # GCC, Clang common_warnings = [] @@ -958,7 +968,7 @@ if selected_platform in platform_list: print("Error: The `vsproj` option is only usable on Windows with Visual Studio.") Exit(255) env["CPPPATH"] = [Dir(path) for path in env["CPPPATH"]] - methods.generate_vs_project(env, GetOption("num_jobs"), env["vsproj_name"]) + methods.generate_vs_project(env, ARGUMENTS, env["vsproj_name"]) methods.generate_cpp_hint_file("cpp.hint") # Check for the existence of headers diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp index 73526fae3e2..4f05d62ffdb 100644 --- a/core/extension/gdextension.cpp +++ b/core/extension/gdextension.cpp @@ -603,12 +603,13 @@ Ref GDExtensionResourceLoader::load(const String &p_path, const String } bool compatible = true; - if (VERSION_MAJOR < compatibility_minimum[0]) { - compatible = false; - } else if (VERSION_MINOR < compatibility_minimum[1]) { - compatible = false; - } else if (VERSION_PATCH < compatibility_minimum[2]) { - compatible = false; + // Check version lexicographically. + if (VERSION_MAJOR != compatibility_minimum[0]) { + compatible = VERSION_MAJOR > compatibility_minimum[0]; + } else if (VERSION_MINOR != compatibility_minimum[1]) { + compatible = VERSION_MINOR > compatibility_minimum[1]; + } else { + compatible = VERSION_PATCH >= compatibility_minimum[2]; } if (!compatible) { if (r_error) { diff --git a/core/input/input.cpp b/core/input/input.cpp index cf8d71b9a74..0e691aaec7f 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -113,6 +113,7 @@ void Input::_bind_methods() { ClassDB::bind_method(D_METHOD("get_joy_axis", "device", "axis"), &Input::get_joy_axis); ClassDB::bind_method(D_METHOD("get_joy_name", "device"), &Input::get_joy_name); ClassDB::bind_method(D_METHOD("get_joy_guid", "device"), &Input::get_joy_guid); + ClassDB::bind_method(D_METHOD("should_ignore_device", "vendor_id", "product_id"), &Input::should_ignore_device); ClassDB::bind_method(D_METHOD("get_connected_joypads"), &Input::get_connected_joypads); ClassDB::bind_method(D_METHOD("get_joy_vibration_strength", "device"), &Input::get_joy_vibration_strength); ClassDB::bind_method(D_METHOD("get_joy_vibration_duration", "device"), &Input::get_joy_vibration_duration); @@ -472,7 +473,8 @@ void Input::joy_connection_changed(int p_idx, bool p_connected, String p_name, S } joy_names[p_idx] = js; - emit_signal(SNAME("joy_connection_changed"), p_idx, p_connected); + // Ensure this signal is emitted on the main thread, as some platforms (e.g. Linux) call this from a different thread. + call_deferred("emit_signal", SNAME("joy_connection_changed"), p_idx, p_connected); } Vector3 Input::get_gravity() const { @@ -1498,6 +1500,11 @@ String Input::get_joy_guid(int p_device) const { return joy_names[p_device].uid; } +bool Input::should_ignore_device(int p_vendor_id, int p_product_id) const { + uint32_t full_id = (((uint32_t)p_vendor_id) << 16) | ((uint16_t)p_product_id); + return ignored_device_ids.has(full_id); +} + TypedArray Input::get_connected_joypads() { TypedArray ret; HashMap::Iterator elem = joy_names.begin(); @@ -1542,6 +1549,27 @@ Input::Input() { } } + String env_ignore_devices = OS::get_singleton()->get_environment("SDL_GAMECONTROLLER_IGNORE_DEVICES"); + if (!env_ignore_devices.is_empty()) { + Vector entries = env_ignore_devices.split(","); + for (int i = 0; i < entries.size(); i++) { + Vector vid_pid = entries[i].split("/"); + + if (vid_pid.size() < 2) { + continue; + } + + print_verbose(vformat("Device Ignored -- Vendor: %s Product: %s", vid_pid[0], vid_pid[1])); + const uint16_t vid_unswapped = vid_pid[0].hex_to_int(); + const uint16_t pid_unswapped = vid_pid[1].hex_to_int(); + const uint16_t vid = BSWAP16(vid_unswapped); + const uint16_t pid = BSWAP16(pid_unswapped); + + uint32_t full_id = (((uint32_t)vid) << 16) | ((uint16_t)pid); + ignored_device_ids.insert(full_id); + } + } + legacy_just_pressed_behavior = GLOBAL_DEF("input_devices/compatibility/legacy_just_pressed_behavior", false); if (Engine::get_singleton()->is_editor_hint()) { // Always use standard behavior in the editor. diff --git a/core/input/input.h b/core/input/input.h index 9cc596ee903..ec16871b728 100644 --- a/core/input/input.h +++ b/core/input/input.h @@ -154,6 +154,9 @@ private: VelocityTrack mouse_velocity_track; HashMap touch_velocity_track; HashMap joy_names; + + HashSet ignored_device_ids; + int fallback_mapping = -1; CursorShape default_shape = CURSOR_ARROW; @@ -328,6 +331,7 @@ public: bool is_joy_known(int p_device); String get_joy_guid(int p_device) const; + bool should_ignore_device(int p_vendor_id, int p_product_id) const; void set_fallback_mapping(String p_guid); void flush_buffered_events(); diff --git a/core/io/remote_filesystem_client.h b/core/io/remote_filesystem_client.h index 42eba98eb10..fcb5c1cfc3c 100644 --- a/core/io/remote_filesystem_client.h +++ b/core/io/remote_filesystem_client.h @@ -44,8 +44,8 @@ protected: String _get_cache_path() { return cache_path; } struct FileCache { String path; // Local path (as in "folder/to/file.png") - uint64_t server_modified_time; // MD5 checksum. - uint64_t modified_time; + uint64_t server_modified_time = 0; // MD5 checksum. + uint64_t modified_time = 0; }; virtual bool _is_configured() { return !cache_path.is_empty(); } // Can be re-implemented per platform. If so, feel free to ignore get_cache_path() diff --git a/core/object/class_db.h b/core/object/class_db.h index ce64336a45c..0afdbbb588d 100644 --- a/core/object/class_db.h +++ b/core/object/class_db.h @@ -187,6 +187,7 @@ public: template static void register_class(bool p_virtual = false) { GLOBAL_LOCK_FUNCTION; + static_assert(TypesAreSame::value, "Class not declared properly, please use GDCLASS."); T::initialize_class(); ClassInfo *t = classes.getptr(T::get_class_static()); ERR_FAIL_COND(!t); @@ -201,6 +202,7 @@ public: template static void register_abstract_class() { GLOBAL_LOCK_FUNCTION; + static_assert(TypesAreSame::value, "Class not declared properly, please use GDCLASS."); T::initialize_class(); ClassInfo *t = classes.getptr(T::get_class_static()); ERR_FAIL_COND(!t); @@ -221,6 +223,7 @@ public: template static void register_custom_instance_class() { GLOBAL_LOCK_FUNCTION; + static_assert(TypesAreSame::value, "Class not declared properly, please use GDCLASS."); T::initialize_class(); ClassInfo *t = classes.getptr(T::get_class_static()); ERR_FAIL_COND(!t); diff --git a/core/object/object.h b/core/object/object.h index a3e9d025ea8..367148d00de 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -382,6 +382,7 @@ private: friend class ::ClassDB; \ \ public: \ + typedef m_class self_type; \ static constexpr bool _class_is_enabled = !bool(GD_IS_DEFINED(ClassDB_Disable_##m_class)) && m_inherits::_class_is_enabled; \ virtual String get_class() const override { \ if (_get_extension()) { \ @@ -551,6 +552,8 @@ class ScriptInstance; class Object { public: + typedef Object self_type; + enum ConnectFlags { CONNECT_DEFERRED = 1, CONNECT_PERSIST = 2, // hint for scene to save this connection diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index 12e64237248..9ec8a406b17 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -1493,9 +1493,9 @@ String String::num(double p_num, int p_decimals) { if (p_decimals < 0) { p_decimals = 14; - const double abs_num = ABS(p_num); + const double abs_num = Math::abs(p_num); if (abs_num > 10) { - // We want to align the digits to the above sane default, so we only + // We want to align the digits to the above reasonable default, so we only // need to subtract log10 for numbers with a positive power of ten. p_decimals -= (int)floor(log10(abs_num)); } @@ -4869,8 +4869,8 @@ String String::sprintf(const Array &values, bool *error) const { } double value = values[value_index]; - bool is_negative = (value < 0); - String str = String::num(ABS(value), min_decimals); + bool is_negative = signbit(value); + String str = String::num(Math::abs(value), min_decimals); const bool is_finite = Math::is_finite(value); // Pad decimals out. @@ -4932,7 +4932,7 @@ String String::sprintf(const Array &values, bool *error) const { String str = "("; for (int i = 0; i < count; i++) { double val = vec[i]; - String number_str = String::num(ABS(val), min_decimals); + String number_str = String::num(Math::abs(val), min_decimals); const bool is_finite = Math::is_finite(val); // Pad decimals out. diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index 10a267e5a99..8a0289898de 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -1754,11 +1754,10 @@ String Variant::stringify(int recursion_count) const { case COLOR: return operator Color(); case DICTIONARY: { + ERR_FAIL_COND_V_MSG(recursion_count > MAX_RECURSION, "{ ... }", "Maximum dictionary recursion reached!"); + recursion_count++; + const Dictionary &d = *reinterpret_cast(_data._mem); - if (recursion_count > MAX_RECURSION) { - ERR_PRINT("Maximum dictionary recursion reached!"); - return "{ ... }"; - } // Add leading and trailing space to Dictionary printing. This distinguishes it // from array printing on fonts that have similar-looking {} and [] characters. @@ -1768,7 +1767,6 @@ String Variant::stringify(int recursion_count) const { Vector<_VariantStrPair> pairs; - recursion_count++; for (List::Element *E = keys.front(); E; E = E->next()) { _VariantStrPair sp; sp.key = stringify_variant_clean(E->get(), recursion_count); @@ -1787,6 +1785,7 @@ String Variant::stringify(int recursion_count) const { return str; } + // Packed arrays cannot contain recursive structures, the recursion_count increment is not needed. case PACKED_VECTOR2_ARRAY: { return stringify_vector(operator Vector(), recursion_count); } @@ -1815,13 +1814,10 @@ String Variant::stringify(int recursion_count) const { return stringify_vector(operator Vector(), recursion_count); } case ARRAY: { - Array arr = operator Array(); - if (recursion_count > MAX_RECURSION) { - ERR_PRINT("Maximum array recursion reached!"); - return "[...]"; - } + ERR_FAIL_COND_V_MSG(recursion_count > MAX_RECURSION, "[...]", "Maximum array recursion reached!"); + recursion_count++; - return stringify_vector(arr, recursion_count); + return stringify_vector(operator Array(), recursion_count); } case OBJECT: { if (_get_obj().obj) { diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp index 33207509949..b7bdf1d97a6 100644 --- a/core/variant/variant_parser.cpp +++ b/core/variant/variant_parser.cpp @@ -1708,7 +1708,7 @@ static String rtos_fix(double p_value) { } } -Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int recursion_count) { +Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int p_recursion_count) { switch (p_variant.get_type()) { case Variant::NIL: { p_store_string_func(p_store_string_ud, "null"); @@ -1730,10 +1730,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } break; case Variant::STRING: { String str = p_variant; - str = "\"" + str.c_escape_multiline() + "\""; p_store_string_func(p_store_string_ud, str); } break; + + // Math types. case Variant::VECTOR2: { Vector2 v = p_variant; p_store_string_func(p_store_string_ud, "Vector2(" + rtos_fix(v.x) + ", " + rtos_fix(v.y) + ")"); @@ -1745,12 +1746,10 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str case Variant::RECT2: { Rect2 aabb = p_variant; p_store_string_func(p_store_string_ud, "Rect2(" + rtos_fix(aabb.position.x) + ", " + rtos_fix(aabb.position.y) + ", " + rtos_fix(aabb.size.x) + ", " + rtos_fix(aabb.size.y) + ")"); - } break; case Variant::RECT2I: { Rect2i aabb = p_variant; p_store_string_func(p_store_string_ud, "Rect2i(" + itos(aabb.position.x) + ", " + itos(aabb.position.y) + ", " + itos(aabb.size.x) + ", " + itos(aabb.size.y) + ")"); - } break; case Variant::VECTOR3: { Vector3 v = p_variant; @@ -1771,17 +1770,14 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str case Variant::PLANE: { Plane p = p_variant; p_store_string_func(p_store_string_ud, "Plane(" + rtos_fix(p.normal.x) + ", " + rtos_fix(p.normal.y) + ", " + rtos_fix(p.normal.z) + ", " + rtos_fix(p.d) + ")"); - } break; case Variant::AABB: { AABB aabb = p_variant; p_store_string_func(p_store_string_ud, "AABB(" + rtos_fix(aabb.position.x) + ", " + rtos_fix(aabb.position.y) + ", " + rtos_fix(aabb.position.z) + ", " + rtos_fix(aabb.size.x) + ", " + rtos_fix(aabb.size.y) + ", " + rtos_fix(aabb.size.z) + ")"); - } break; case Variant::QUATERNION: { Quaternion quaternion = p_variant; p_store_string_func(p_store_string_ud, "Quaternion(" + rtos_fix(quaternion.x) + ", " + rtos_fix(quaternion.y) + ", " + rtos_fix(quaternion.z) + ", " + rtos_fix(quaternion.w) + ")"); - } break; case Variant::TRANSFORM2D: { String s = "Transform2D("; @@ -1796,7 +1792,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } p_store_string_func(p_store_string_ud, s + ")"); - } break; case Variant::BASIS: { String s = "Basis("; @@ -1811,7 +1806,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } p_store_string_func(p_store_string_ud, s + ")"); - } break; case Variant::TRANSFORM3D: { String s = "Transform3D("; @@ -1845,30 +1839,23 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, s + ")"); } break; - // misc types + // Misc types. case Variant::COLOR: { Color c = p_variant; p_store_string_func(p_store_string_ud, "Color(" + rtos_fix(c.r) + ", " + rtos_fix(c.g) + ", " + rtos_fix(c.b) + ", " + rtos_fix(c.a) + ")"); - } break; case Variant::STRING_NAME: { String str = p_variant; - str = "&\"" + str.c_escape() + "\""; p_store_string_func(p_store_string_ud, str); - } break; case Variant::NODE_PATH: { String str = p_variant; - str = "NodePath(\"" + str.c_escape() + "\")"; p_store_string_func(p_store_string_ud, str); - } break; - case Variant::RID: { RID rid = p_variant; - if (rid == RID()) { p_store_string_func(p_store_string_ud, "RID()"); } else { @@ -1885,6 +1872,13 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } break; case Variant::OBJECT: { + if (unlikely(p_recursion_count > MAX_RECURSION)) { + ERR_PRINT("Max recursion reached"); + p_store_string_func(p_store_string_ud, "null"); + return OK; + } + p_recursion_count++; + Object *obj = p_variant.get_validated_object(); if (!obj) { @@ -1934,21 +1928,20 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } p_store_string_func(p_store_string_ud, "\"" + E.name + "\":"); - write(obj->get(E.name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud); + write(obj->get(E.name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count); } } p_store_string_func(p_store_string_ud, ")\n"); - } break; case Variant::DICTIONARY: { Dictionary dict = p_variant; - if (recursion_count > MAX_RECURSION) { + if (unlikely(p_recursion_count > MAX_RECURSION)) { ERR_PRINT("Max recursion reached"); p_store_string_func(p_store_string_ud, "{}"); } else { - recursion_count++; + p_recursion_count++; List keys; dict.get_key_list(&keys); @@ -1961,9 +1954,9 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, "{\n"); for (List::Element *E = keys.front(); E; E = E->next()) { - write(E->get(), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, recursion_count); + write(E->get(), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count); p_store_string_func(p_store_string_ud, ": "); - write(dict[E->get()], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, recursion_count); + write(dict[E->get()], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count); if (E->next()) { p_store_string_func(p_store_string_ud, ",\n"); } else { @@ -1973,7 +1966,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, "}"); } - } break; case Variant::ARRAY: { @@ -2009,11 +2001,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, "]("); } - if (recursion_count > MAX_RECURSION) { + if (unlikely(p_recursion_count > MAX_RECURSION)) { ERR_PRINT("Max recursion reached"); p_store_string_func(p_store_string_ud, "[]"); } else { - recursion_count++; + p_recursion_count++; p_store_string_func(p_store_string_ud, "["); int len = array.size(); @@ -2021,7 +2013,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str if (i > 0) { p_store_string_func(p_store_string_ud, ", "); } - write(array[i], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, recursion_count); + write(array[i], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count); } p_store_string_func(p_store_string_ud, "]"); @@ -2030,7 +2022,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str if (array.get_typed_builtin() != Variant::NIL) { p_store_string_func(p_store_string_ud, ")"); } - } break; case Variant::PACKED_BYTE_ARRAY: { @@ -2048,7 +2039,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } p_store_string_func(p_store_string_ud, ")"); - } break; case Variant::PACKED_INT32_ARRAY: { p_store_string_func(p_store_string_ud, "PackedInt32Array("); @@ -2065,7 +2055,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } p_store_string_func(p_store_string_ud, ")"); - } break; case Variant::PACKED_INT64_ARRAY: { p_store_string_func(p_store_string_ud, "PackedInt64Array("); @@ -2082,7 +2071,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } p_store_string_func(p_store_string_ud, ")"); - } break; case Variant::PACKED_FLOAT32_ARRAY: { p_store_string_func(p_store_string_ud, "PackedFloat32Array("); @@ -2098,7 +2086,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } p_store_string_func(p_store_string_ud, ")"); - } break; case Variant::PACKED_FLOAT64_ARRAY: { p_store_string_func(p_store_string_ud, "PackedFloat64Array("); @@ -2114,7 +2101,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } p_store_string_func(p_store_string_ud, ")"); - } break; case Variant::PACKED_STRING_ARRAY: { p_store_string_func(p_store_string_ud, "PackedStringArray("); @@ -2130,7 +2116,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } p_store_string_func(p_store_string_ud, ")"); - } break; case Variant::PACKED_VECTOR2_ARRAY: { p_store_string_func(p_store_string_ud, "PackedVector2Array("); @@ -2146,7 +2131,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } p_store_string_func(p_store_string_ud, ")"); - } break; case Variant::PACKED_VECTOR3_ARRAY: { p_store_string_func(p_store_string_ud, "PackedVector3Array("); @@ -2162,7 +2146,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } p_store_string_func(p_store_string_ud, ")"); - } break; case Variant::PACKED_COLOR_ARRAY: { p_store_string_func(p_store_string_ud, "PackedColorArray("); @@ -2178,8 +2161,8 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } p_store_string_func(p_store_string_ud, ")"); - } break; + default: { ERR_PRINT("Unknown variant type"); return ERR_BUG; diff --git a/core/variant/variant_parser.h b/core/variant/variant_parser.h index 88be99e5511..8505fff739a 100644 --- a/core/variant/variant_parser.h +++ b/core/variant/variant_parser.h @@ -160,7 +160,7 @@ public: typedef Error (*StoreStringFunc)(void *ud, const String &p_string); typedef String (*EncodeResourceFunc)(void *ud, const Ref &p_resource); - static Error write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int recursion_count = 0); + static Error write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int p_recursion_count = 0); static Error write_to_string(const Variant &p_variant, String &r_string, EncodeResourceFunc p_encode_res_func = nullptr, void *p_encode_res_ud = nullptr); }; diff --git a/doc/classes/CollisionPolygon2D.xml b/doc/classes/CollisionPolygon2D.xml index 4ad88d49bc3..f7dd2498564 100644 --- a/doc/classes/CollisionPolygon2D.xml +++ b/doc/classes/CollisionPolygon2D.xml @@ -5,7 +5,7 @@ A node that provides a thickened polygon shape (a prism) to a [CollisionObject2D] parent and allows to edit it. The polygon can be concave or convex. This can give a detection shape to an [Area2D] or turn [PhysicsBody2D] into a solid object. - [b]Warning:[/b] A non-uniformly scaled [CollisionShape3D] will likely not behave as expected. Make sure to keep its scale the same on all axes and adjust its shape resource instead. + [b]Warning:[/b] A non-uniformly scaled [CollisionShape2D] will likely not behave as expected. Make sure to keep its scale the same on all axes and adjust its shape resource instead. diff --git a/doc/classes/ConvexPolygonShape2D.xml b/doc/classes/ConvexPolygonShape2D.xml index d131df3d278..fe3566e6875 100644 --- a/doc/classes/ConvexPolygonShape2D.xml +++ b/doc/classes/ConvexPolygonShape2D.xml @@ -6,7 +6,7 @@ A 2D convex polygon shape, intended for use in physics. Used internally in [CollisionPolygon2D] when it's in [code]BUILD_SOLIDS[/code] mode. [ConvexPolygonShape2D] is [i]solid[/i], which means it detects collisions from objects that are fully inside it, unlike [ConcavePolygonShape2D] which is hollow. This makes it more suitable for both detection and physics. - [b]Convex decomposition:[/b] A concave polygon can be split up into several convex polygons. This allows dynamic physics bodies to have complex concave collisions (at a performance cost) and can be achieved by using several [ConvexPolygonShape3D] nodes or by using the [CollisionPolygon2D] node in [code]BUILD_SOLIDS[/code] mode. To generate a collision polygon from a sprite, select the [Sprite2D] node, go to the [b]Sprite2D[/b] menu that appears above the viewport, and choose [b]Create Polygon2D Sibling[/b]. + [b]Convex decomposition:[/b] A concave polygon can be split up into several convex polygons. This allows dynamic physics bodies to have complex concave collisions (at a performance cost) and can be achieved by using several [ConvexPolygonShape2D] nodes or by using the [CollisionPolygon2D] node in [code]BUILD_SOLIDS[/code] mode. To generate a collision polygon from a sprite, select the [Sprite2D] node, go to the [b]Sprite2D[/b] menu that appears above the viewport, and choose [b]Create Polygon2D Sibling[/b]. [b]Performance:[/b] [ConvexPolygonShape2D] is faster to check collisions against compared to [ConcavePolygonShape2D], but it is slower than primitive collision shapes such as [CircleShape2D] and [RectangleShape2D]. Its use should generally be limited to medium-sized objects that cannot have their collision accurately represented by primitive shapes. diff --git a/doc/classes/CylinderShape3D.xml b/doc/classes/CylinderShape3D.xml index 1492e095911..4d3af5b6a9d 100644 --- a/doc/classes/CylinderShape3D.xml +++ b/doc/classes/CylinderShape3D.xml @@ -4,9 +4,9 @@ A 3D cylinder shape used for physics collision. - A 2D capsule shape, intended for use in physics. Usually used to provide a shape for a [CollisionShape3D]. + A 3D cylinder shape, intended for use in physics. Usually used to provide a shape for a [CollisionShape3D]. [b]Note:[/b] There are several known bugs with cylinder collision shapes. Using [CapsuleShape3D] or [BoxShape3D] instead is recommended. - [b]Performance:[/b] [CylinderShape3D] is fast to check collisions against, but it is slower than [CapsuleShape3D], [BoxShape3D], and [CylinderShape3D]. + [b]Performance:[/b] [CylinderShape3D] is fast to check collisions against, but it is slower than [CapsuleShape3D], [BoxShape3D], and [SphereShape3D]. https://godotengine.org/asset-library/asset/678 diff --git a/doc/classes/GPUParticles3D.xml b/doc/classes/GPUParticles3D.xml index f03c8f7d419..7e2873487b3 100644 --- a/doc/classes/GPUParticles3D.xml +++ b/doc/classes/GPUParticles3D.xml @@ -59,6 +59,7 @@ Particle draw order. Uses [enum DrawOrder] values. + [b]Note:[/b] [constant DRAW_ORDER_INDEX] is the only option that supports motion vectors for effects like TAA. It is suggested to use this draw order if the particles are opaque to fix ghosting artifacts. [Mesh] that is drawn for the first draw pass. diff --git a/doc/classes/HTTPClient.xml b/doc/classes/HTTPClient.xml index 39cebf773b2..6c7cc299e53 100644 --- a/doc/classes/HTTPClient.xml +++ b/doc/classes/HTTPClient.xml @@ -41,6 +41,7 @@ Returns the response's body length. [b]Note:[/b] Some Web servers may not send a body length. In this case, the value returned will be [code]-1[/code]. If using chunked transfer encoding, the body length will also be [code]-1[/code]. + [b]Note:[/b] This function always returns [code]-1[/code] on the Web platform due to browsers limitations. diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml index cea8e66e528..bed65e277da 100644 --- a/doc/classes/Input.xml +++ b/doc/classes/Input.xml @@ -343,6 +343,15 @@ [b]Note:[/b] This value can be immediately overwritten by the hardware sensor value on Android and iOS. + + + + + + Queries whether an input device should be ignored or not. Devices can be ignored by setting the environment variable [code]SDL_GAMECONTROLLER_IGNORE_DEVICES[/code]. Read the [url=https://wiki.libsdl.org/SDL2]SDL documentation[/url] for more information. + [b]Note:[/b] Some 3rd party tools can contribute to the list of ignored devices. For example, [i]SteamInput[/i] creates virtual devices from physical devices for remapping purposes. To avoid handling the same input device twice, the original device is added to the ignore list. + + diff --git a/doc/classes/LightmapGI.xml b/doc/classes/LightmapGI.xml index 55c6ef5eb5d..2b7875a939d 100644 --- a/doc/classes/LightmapGI.xml +++ b/doc/classes/LightmapGI.xml @@ -117,6 +117,9 @@ The user aborted the lightmap baking operation (typically by clicking the [b]Cancel[/b] button in the progress dialog). + + Lightmap baking failed as the maximum texture size is too small to fit some of the meshes marked for baking. + Ignore environment lighting when baking lightmaps. diff --git a/doc/classes/NavigationAgent3D.xml b/doc/classes/NavigationAgent3D.xml index 2450f849291..82817948aa4 100644 --- a/doc/classes/NavigationAgent3D.xml +++ b/doc/classes/NavigationAgent3D.xml @@ -230,8 +230,8 @@ - [code]type[/code]: Always [constant NavigationPathQueryResult3D.PATH_SEGMENT_TYPE_LINK]. - [code]rid[/code]: The [RID] of the link. - [code]owner[/code]: The object which manages the link (usually [NavigationLink3D]). - - [code]link_entry_position[/code]: If [code]owner[/code] is available and the owner is a [NavigationLink2D], it will contain the global position of the link's point the agent is entering. - - [code]link_exit_position[/code]: If [code]owner[/code] is available and the owner is a [NavigationLink2D], it will contain the global position of the link's point which the agent is exiting. + - [code]link_entry_position[/code]: If [code]owner[/code] is available and the owner is a [NavigationLink3D], it will contain the global position of the link's point the agent is entering. + - [code]link_exit_position[/code]: If [code]owner[/code] is available and the owner is a [NavigationLink3D], it will contain the global position of the link's point which the agent is exiting. diff --git a/doc/classes/NavigationServer3D.xml b/doc/classes/NavigationServer3D.xml index ef437600a1b..db44cbe9d84 100644 --- a/doc/classes/NavigationServer3D.xml +++ b/doc/classes/NavigationServer3D.xml @@ -4,7 +4,7 @@ A server interface for low-level 3D navigation access. - NavigationServer2D is the server that handles navigation maps, regions and agents. It does not handle A* navigation from [AStar3D]. + NavigationServer3D is the server that handles navigation maps, regions and agents. It does not handle A* navigation from [AStar3D]. Maps are made up of regions, which are made of navigation meshes. Together, they define the navigable areas in the 3D world. [b]Note:[/b] Most [NavigationServer3D] changes take effect after the next physics frame and not immediately. This includes all changes made to maps, regions or agents by navigation-related nodes in the scene tree or made through scripts. For two regions to be connected to each other, they must share a similar edge. An edge is considered connected to another if both of its two vertices are at a distance less than [code]edge_connection_margin[/code] to the respective other edge's vertex. diff --git a/doc/classes/PhysicsServer3D.xml b/doc/classes/PhysicsServer3D.xml index b433780e09f..f02a41b771b 100644 --- a/doc/classes/PhysicsServer3D.xml +++ b/doc/classes/PhysicsServer3D.xml @@ -4,7 +4,7 @@ A server interface for low-level 3D physics access. - PhysicsServer2D is the server responsible for all 2D physics. It can directly create and manipulate all physics objects: + PhysicsServer3D is the server responsible for all 3D physics. It can directly create and manipulate all physics objects: - A [i]space[/i] is a self-contained world for a physics simulation. It contains bodies, areas, and joints. Its state can be queried for collision and intersection information, and several parameters of the simulation can be modified. - A [i]shape[/i] is a geometric shape such as a sphere, a box, a cylinder, or a polygon. It can be used for collision detection by adding it to a body/area, possibly with an extra transformation relative to the body/area's origin. Bodies/areas can have multiple (transformed) shapes added to them, and a single shape can be added to bodies/areas multiple times with different local transformations. - A [i]body[/i] is a physical object which can be in static, kinematic, or rigid mode. Its state (such as position and velocity) can be queried and updated. A force integration callback can be set to customize the body's physics. diff --git a/doc/classes/PinJoint3D.xml b/doc/classes/PinJoint3D.xml index c02c4c960ff..34e9f9bd06e 100644 --- a/doc/classes/PinJoint3D.xml +++ b/doc/classes/PinJoint3D.xml @@ -4,7 +4,7 @@ A physics joint that attaches two 3D physics bodies at a single point, allowing them to freely rotate. - A physics joint that attaches two 2D physics bodies at a single point, allowing them to freely rotate. For example, a [RigidBody3D] can be attached to a [StaticBody3D] to create a pendulum or a seesaw. + A physics joint that attaches two 3D physics bodies at a single point, allowing them to freely rotate. For example, a [RigidBody3D] can be attached to a [StaticBody3D] to create a pendulum or a seesaw. diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 9681b6e5126..b6f44e3ba7c 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -1443,6 +1443,7 @@ Returns the name of the video adapter (e.g. "GeForce GTX 1080/PCIe/SSE2"). [b]Note:[/b] When running a headless or server binary, this function returns an empty string. + [b]Note:[/b] On the web platform, some browsers such as Firefox may report a different, fixed GPU name such as "GeForce GTX 980" (regardless of the user's actual GPU model). This is done to make fingerprinting more difficult. diff --git a/doc/classes/ScrollContainer.xml b/doc/classes/ScrollContainer.xml index 9026f4a5d08..8caa9f296e4 100644 --- a/doc/classes/ScrollContainer.xml +++ b/doc/classes/ScrollContainer.xml @@ -50,7 +50,7 @@ Deadzone for touch scrolling. Lower deadzone makes the scrolling more sensitive. - The current horizontal scroll value. + The current horizontal scroll value. [b]Note:[/b] If you are setting this value in the [method Node._ready] function or earlier, it needs to be wrapped with [method Object.set_deferred], since scroll bar's [member Range.max_value] is not initialized yet. [codeblock] func _ready(): @@ -78,12 +78,14 @@ - Emitted when scrolling stops. + Emitted when scrolling stops when dragging the scrollable area [i]with a touch event[/i]. This signal is [i]not[/i] emitted when scrolling by dragging the scrollbar, scrolling with the mouse wheel or scrolling with keyboard/gamepad events. + [b]Note:[/b] This signal is only emitted on Android or iOS, or on desktop/web platforms when [member ProjectSettings.input_devices/pointing/emulate_touch_from_mouse] is enabled. - Emitted when scrolling is started. + Emitted when scrolling starts when dragging the scrollable area w[i]ith a touch event[/i]. This signal is [i]not[/i] emitted when scrolling by dragging the scrollbar, scrolling with the mouse wheel or scrolling with keyboard/gamepad events. + [b]Note:[/b] This signal is only emitted on Android or iOS, or on desktop/web platforms when [member ProjectSettings.input_devices/pointing/emulate_touch_from_mouse] is enabled. diff --git a/doc/classes/SeparationRayShape3D.xml b/doc/classes/SeparationRayShape3D.xml index d8670e40d73..753206cb649 100644 --- a/doc/classes/SeparationRayShape3D.xml +++ b/doc/classes/SeparationRayShape3D.xml @@ -4,7 +4,7 @@ A 3D ray shape used for physics collision that tries to separate itself from any collider. - A 3D ray shape, intended for use in physics. Usually used to provide a shape for a [CollisionShape2D]. When a [SeparationRayShape3D] collides with an object, it tries to separate itself from it by moving its endpoint to the collision point. It can for example be used for spears falling from the sky. + A 3D ray shape, intended for use in physics. Usually used to provide a shape for a [CollisionShape3D]. When a [SeparationRayShape3D] collides with an object, it tries to separate itself from it by moving its endpoint to the collision point. It can for example be used for spears falling from the sky. diff --git a/doc/classes/SurfaceTool.xml b/doc/classes/SurfaceTool.xml index aa486a1843e..bf868f42e62 100644 --- a/doc/classes/SurfaceTool.xml +++ b/doc/classes/SurfaceTool.xml @@ -118,7 +118,7 @@ Removes the index array by expanding the vertex array. - + diff --git a/doc/classes/TreeItem.xml b/doc/classes/TreeItem.xml index 559d38e5cca..ddef2d8d478 100644 --- a/doc/classes/TreeItem.xml +++ b/doc/classes/TreeItem.xml @@ -339,6 +339,13 @@ Returns item's text base writing direction. + + + + + Returns the clipping behavior when the text exceeds the item's bounding rectangle in the given [param column]. By default it is [constant TextServer.OVERRUN_TRIM_ELLIPSIS]. + + @@ -719,6 +726,14 @@ Sets item's text base writing direction. + + + + + + Sets the clipping behavior when the text exceeds the item's bounding rectangle in the given [param column]. + + diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 86405fa3f04..09f3e13d46a 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -1451,7 +1451,7 @@ void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index) { void RasterizerCanvasGLES3::_add_to_batch(uint32_t &r_index, bool &r_batch_broken) { state.canvas_instance_batches[state.current_batch_index].instance_count++; r_index++; - if (r_index >= data.max_instances_per_buffer) { + if (r_index + state.last_item_index >= data.max_instances_per_buffer) { // Copy over all data needed for rendering right away // then go back to recording item commands. glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[state.current_instance_buffer_index]); diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index e6e7dd6f171..798d430d8a8 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -2166,7 +2166,9 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, if (scene_state.current_depth_draw != shader->depth_draw) { switch (shader->depth_draw) { case GLES3::SceneShaderData::DEPTH_DRAW_OPAQUE: { - glDepthMask(p_pass_mode == PASS_MODE_COLOR); + glDepthMask((p_pass_mode == PASS_MODE_COLOR && !GLES3::Config::get_singleton()->use_depth_prepass) || + p_pass_mode == PASS_MODE_DEPTH || + p_pass_mode == PASS_MODE_SHADOW); } break; case GLES3::SceneShaderData::DEPTH_DRAW_ALWAYS: { glDepthMask(GL_TRUE); diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp index 29e9ada72b1..e3cc6d06817 100644 --- a/drivers/gles3/shader_gles3.cpp +++ b/drivers/gles3/shader_gles3.cpp @@ -769,7 +769,7 @@ void ShaderGLES3::initialize(const String &p_general_defines, int p_base_texture print_verbose("Shader '" + name + "' SHA256: " + base_sha256); } - glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_image_units); + glGetInteger64v(GL_MAX_TEXTURE_IMAGE_UNITS, &max_image_units); } void ShaderGLES3::set_shader_cache_dir(const String &p_dir) { diff --git a/drivers/gles3/shader_gles3.h b/drivers/gles3/shader_gles3.h index c095c41e799..7265202ced5 100644 --- a/drivers/gles3/shader_gles3.h +++ b/drivers/gles3/shader_gles3.h @@ -154,7 +154,7 @@ private: static bool shader_cache_save_debug; bool shader_cache_dir_valid = false; - GLint max_image_units = 0; + int64_t max_image_units = 0; enum StageType { STAGE_TYPE_VERTEX, diff --git a/drivers/gles3/storage/config.cpp b/drivers/gles3/storage/config.cpp index 77a4553c763..03dde88d4b4 100644 --- a/drivers/gles3/storage/config.cpp +++ b/drivers/gles3/storage/config.cpp @@ -53,9 +53,9 @@ Config::Config() { singleton = this; { - GLint max_extensions = 0; - glGetIntegerv(GL_NUM_EXTENSIONS, &max_extensions); - for (int i = 0; i < max_extensions; i++) { + int64_t max_extensions = 0; + glGetInteger64v(GL_NUM_EXTENSIONS, &max_extensions); + for (int64_t i = 0; i < max_extensions; i++) { const GLubyte *s = glGetStringi(GL_EXTENSIONS, i); if (!s) { break; @@ -88,11 +88,11 @@ Config::Config() { rgtc_supported = extensions.has("GL_EXT_texture_compression_rgtc") || extensions.has("GL_ARB_texture_compression_rgtc") || extensions.has("EXT_texture_compression_rgtc"); #endif - glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &max_vertex_texture_image_units); - glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_texture_image_units); - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); - glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_uniform_buffer_size); - glGetIntegerv(GL_MAX_VIEWPORT_DIMS, max_viewport_size); + glGetInteger64v(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &max_vertex_texture_image_units); + glGetInteger64v(GL_MAX_TEXTURE_IMAGE_UNITS, &max_texture_image_units); + glGetInteger64v(GL_MAX_TEXTURE_SIZE, &max_texture_size); + glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &max_uniform_buffer_size); + glGetInteger64v(GL_MAX_VIEWPORT_DIMS, max_viewport_size); support_anisotropic_filter = extensions.has("GL_EXT_texture_filter_anisotropic"); if (support_anisotropic_filter) { diff --git a/drivers/gles3/storage/config.h b/drivers/gles3/storage/config.h index 623f0442bdf..6b90c8c359d 100644 --- a/drivers/gles3/storage/config.h +++ b/drivers/gles3/storage/config.h @@ -58,14 +58,14 @@ public: bool use_nearest_mip_filter = false; bool use_depth_prepass = true; - int max_vertex_texture_image_units = 0; - int max_texture_image_units = 0; - int max_texture_size = 0; - int max_viewport_size[2] = { 0, 0 }; - int max_uniform_buffer_size = 0; - int max_renderable_elements = 0; - int max_renderable_lights = 0; - int max_lights_per_object = 0; + int64_t max_vertex_texture_image_units = 0; + int64_t max_texture_image_units = 0; + int64_t max_texture_size = 0; + int64_t max_viewport_size[2] = { 0, 0 }; + int64_t max_uniform_buffer_size = 0; + int64_t max_renderable_elements = 0; + int64_t max_renderable_lights = 0; + int64_t max_lights_per_object = 0; // TODO implement wireframe in OpenGL // bool generate_wireframes; diff --git a/drivers/gles3/storage/mesh_storage.cpp b/drivers/gles3/storage/mesh_storage.cpp index f3be6f509e2..a96a491517f 100644 --- a/drivers/gles3/storage/mesh_storage.cpp +++ b/drivers/gles3/storage/mesh_storage.cpp @@ -1285,13 +1285,17 @@ void MeshStorage::multimesh_allocate_data(RID p_multimesh, int p_instances, RS:: multimesh->data_cache_used_dirty_regions = 0; } + // If we have either color or custom data, reserve space for both to make data handling logic simpler. + // This way we can always treat them both as a single, compressed uvec4. + int color_and_custom_strides = (p_use_colors || p_use_custom_data) ? 2 : 0; + multimesh->instances = p_instances; multimesh->xform_format = p_transform_format; multimesh->uses_colors = p_use_colors; multimesh->color_offset_cache = p_transform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12; multimesh->uses_custom_data = p_use_custom_data; - multimesh->custom_data_offset_cache = multimesh->color_offset_cache + (p_use_colors ? 2 : 0); - multimesh->stride_cache = multimesh->custom_data_offset_cache + (p_use_custom_data ? 2 : 0); + multimesh->custom_data_offset_cache = multimesh->color_offset_cache + color_and_custom_strides; + multimesh->stride_cache = multimesh->custom_data_offset_cache + color_and_custom_strides; multimesh->buffer_set = false; multimesh->data_cache = Vector(); @@ -1685,14 +1689,16 @@ void MeshStorage::multimesh_set_buffer(RID p_multimesh, const Vector &p_b // Color and custom need to be packed so copy buffer to data_cache and pack. _multimesh_make_local(multimesh); - multimesh->data_cache = p_buffer; - float *w = multimesh->data_cache.ptrw(); uint32_t old_stride = multimesh->xform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12; old_stride += multimesh->uses_colors ? 4 : 0; old_stride += multimesh->uses_custom_data ? 4 : 0; ERR_FAIL_COND(p_buffer.size() != (multimesh->instances * (int)old_stride)); + multimesh->data_cache = p_buffer; + + float *w = multimesh->data_cache.ptrw(); + for (int i = 0; i < multimesh->instances; i++) { { float *dataptr = w + i * old_stride; diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp index 45f9f14dab2..a80b7d449e6 100644 --- a/drivers/unix/file_access_unix.cpp +++ b/drivers/unix/file_access_unix.cpp @@ -108,10 +108,7 @@ Error FileAccessUnix::open_internal(const String &p_path, int p_mode_flags) { last_error = ERR_FILE_CANT_OPEN; return last_error; } - // Fix temporary file permissions (defaults to 0600 instead of 0666 & ~umask). - mode_t mask = umask(022); - umask(mask); - fchmod(fd, 0666 & ~mask); + fchmod(fd, 0666); path = String::utf8(cs.ptr()); f = fdopen(fd, mode_string); diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 23c69198544..517f2b78a82 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -2607,7 +2607,7 @@ Error RenderingDeviceVulkan::_texture_update(RID p_texture, uint32_t p_layer, co vkCmdCopyBufferToImage(command_buffer, staging_buffer_blocks[staging_buffer_current].buffer, texture->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &buffer_image_copy); - staging_buffer_blocks.write[staging_buffer_current].fill_amount += alloc_size; + staging_buffer_blocks.write[staging_buffer_current].fill_amount = alloc_offset + alloc_size; } } } diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index af7163eec15..0b2c2bea154 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -1154,15 +1154,6 @@ Ref EditorData::get_script_icon(const Ref