diff options
81 files changed, 631 insertions, 575 deletions
diff --git a/.github/actions/godot-deps/action.yml b/.github/actions/godot-deps/action.yml index ee4d7d3751..e99167ff2b 100644 --- a/.github/actions/godot-deps/action.yml +++ b/.github/actions/godot-deps/action.yml @@ -12,7 +12,7 @@ runs: steps: # Use python 3.x release (works cross platform) - name: Set up Python 3.x - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: # Semantic version range syntax or exact version of a Python version python-version: ${{ inputs.python-version }} diff --git a/.github/actions/upload-artifact/action.yml b/.github/actions/upload-artifact/action.yml index bc1871b914..ae0e634cbf 100644 --- a/.github/actions/upload-artifact/action.yml +++ b/.github/actions/upload-artifact/action.yml @@ -12,7 +12,7 @@ runs: using: "composite" steps: - name: Upload Godot Artifact - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{ inputs.name }} path: ${{ inputs.path }} diff --git a/.github/workflows/android_builds.yml b/.github/workflows/android_builds.yml index a9a580247b..4f54f6629e 100644 --- a/.github/workflows/android_builds.yml +++ b/.github/workflows/android_builds.yml @@ -17,7 +17,7 @@ jobs: name: Template (target=release, tools=no) steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 # Azure repositories are not reliable, we need to prevent azure giving us packages. - name: Make apt sources.list use the default Ubuntu repositories @@ -27,8 +27,9 @@ jobs: sudo apt-get update - name: Set up Java 11 - uses: actions/setup-java@v1 + uses: actions/setup-java@v3 with: + distribution: temurin java-version: 11 - name: Setup Godot build cache @@ -38,19 +39,19 @@ jobs: - name: Setup python and scons uses: ./.github/actions/godot-deps - - name: Compilation (armv7) + - name: Compilation (arm32) uses: ./.github/actions/godot-build with: - sconsflags: ${{ env.SCONSFLAGS }} android_arch=armv7 + sconsflags: ${{ env.SCONSFLAGS }} arch=arm32 platform: android target: release tools: false tests: false - - name: Compilation (arm64v8) + - name: Compilation (arm64) uses: ./.github/actions/godot-build with: - sconsflags: ${{ env.SCONSFLAGS }} android_arch=arm64v8 + sconsflags: ${{ env.SCONSFLAGS }} arch=arm64 platform: android target: release tools: false diff --git a/.github/workflows/ios_builds.yml b/.github/workflows/ios_builds.yml index 03277edc1d..bc00fad569 100644 --- a/.github/workflows/ios_builds.yml +++ b/.github/workflows/ios_builds.yml @@ -17,7 +17,7 @@ jobs: name: Template (target=release, tools=no) steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Godot build cache uses: ./.github/actions/godot-cache @@ -26,7 +26,7 @@ jobs: - name: Setup python and scons uses: ./.github/actions/godot-deps - - name: Compilation (arm64v8) + - name: Compilation (arm64) uses: ./.github/actions/godot-build with: sconsflags: ${{ env.SCONSFLAGS }} diff --git a/.github/workflows/javascript_builds.yml b/.github/workflows/javascript_builds.yml index 00c79e8ba0..54bde92b16 100644 --- a/.github/workflows/javascript_builds.yml +++ b/.github/workflows/javascript_builds.yml @@ -19,18 +19,10 @@ jobs: name: Template (target=release, tools=no) steps: - - uses: actions/checkout@v2 - - # Additional cache for Emscripten generated system libraries - - name: Load Emscripten cache - id: javascript-template-emscripten-cache - uses: actions/cache@v2 - with: - path: ${{env.EM_CACHE_FOLDER}} - key: ${{env.EM_VERSION}}-${{github.job}} + - uses: actions/checkout@v3 - name: Set up Emscripten latest - uses: mymindstorm/setup-emsdk@v10 + uses: mymindstorm/setup-emsdk@v11 with: version: ${{env.EM_VERSION}} actions-cache-folder: ${{env.EM_CACHE_FOLDER}} diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index dbb72ae095..2e8bd101e5 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -4,7 +4,7 @@ on: [push, pull_request] # Global Settings env: # Only used for the cache key. Increment version to force clean build. - GODOT_BASE_BRANCH: master-v2 + GODOT_BASE_BRANCH: master SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes DOTNET_NOLOGO: true DOTNET_CLI_TELEMETRY_OPTOUT: false @@ -28,7 +28,7 @@ jobs: tests: false # Disabled due freeze caused by mix Mono build and CI sconsflags: module_mono_enabled=yes doc-test: true - bin: "./bin/godot.linuxbsd.opt.tools.64.mono" + bin: "./bin/godot.linuxbsd.opt.tools.x86_64.mono" build-mono: true proj-conv: true artifact: true @@ -43,7 +43,7 @@ jobs: # Can be turned off for PRs that intentionally break compat with godot-cpp, # until both the upstream PR and the matching godot-cpp changes are merged. godot-cpp-test: true - bin: "./bin/godot.linuxbsd.double.tools.64.san" + bin: "./bin/godot.linuxbsd.double.tools.x86_64.san" build-mono: false # Skip 2GiB artifact speeding up action. artifact: false @@ -54,7 +54,7 @@ jobs: tools: true tests: true sconsflags: use_asan=yes use_ubsan=yes use_llvm=yes linker=lld - bin: "./bin/godot.linuxbsd.tools.64.llvm.san" + bin: "./bin/godot.linuxbsd.tools.x86_64.llvm.san" build-mono: false # Skip 2GiB artifact speeding up action. artifact: false @@ -77,7 +77,7 @@ jobs: artifact: true steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Linux dependencies shell: bash @@ -102,7 +102,7 @@ jobs: uses: ./.github/actions/godot-deps - name: Set up .NET Sdk - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v2 if: ${{ matrix.build-mono }} with: dotnet-version: '6.0.x' @@ -195,7 +195,7 @@ jobs: # Checkout godot-cpp - name: Checkout godot-cpp if: ${{ matrix.godot-cpp-test }} - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: godotengine/godot-cpp submodules: 'recursive' diff --git a/.github/workflows/macos_builds.yml b/.github/workflows/macos_builds.yml index 0ad0995bb7..be1fb8de85 100644 --- a/.github/workflows/macos_builds.yml +++ b/.github/workflows/macos_builds.yml @@ -4,7 +4,7 @@ on: [push, pull_request] # Global Settings env: # Only used for the cache key. Increment version to force clean build. - GODOT_BASE_BRANCH: master-v3 + GODOT_BASE_BRANCH: master SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes concurrency: @@ -24,7 +24,7 @@ jobs: target: release_debug tools: true tests: true - bin: "./bin/godot.macos.opt.tools.64" + bin: "./bin/godot.macos.opt.tools.x86_64" - name: Template (target=release, tools=no) cache-name: macos-template @@ -34,7 +34,7 @@ jobs: sconsflags: debug_symbols=no steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - 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 fea82791ed..557b67c970 100644 --- a/.github/workflows/static_checks.yml +++ b/.github/workflows/static_checks.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-20.04 steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Azure repositories are not reliable, we need to prevent Azure giving us packages. - name: Make apt sources.list use the default Ubuntu repositories diff --git a/.github/workflows/windows_builds.yml b/.github/workflows/windows_builds.yml index e04d49adde..9033e1ab1d 100644 --- a/.github/workflows/windows_builds.yml +++ b/.github/workflows/windows_builds.yml @@ -5,7 +5,7 @@ on: [push, pull_request] # SCONS_CACHE for windows must be set in the build environment env: # Only used for the cache key. Increment version to force clean build. - GODOT_BASE_BRANCH: master-v2 + GODOT_BASE_BRANCH: master SCONSFLAGS: verbose=yes warnings=all werror=yes module_text_server_fb_enabled=yes SCONS_CACHE_MSVC_CONFIG: true @@ -29,7 +29,7 @@ jobs: tests: true # Skip debug symbols, they're way too big with MSVC. sconsflags: debug_symbols=no - bin: "./bin/godot.windows.opt.tools.64.exe" + bin: "./bin/godot.windows.opt.tools.x86_64.exe" - name: Template (target=release, tools=no) cache-name: windows-template @@ -39,7 +39,7 @@ jobs: sconsflags: debug_symbols=no steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Godot build cache uses: ./.github/actions/godot-cache diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e5565e72ed..a1e8d3a59d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -37,7 +37,7 @@ Godot runs on a large variety of platforms and operating systems and devices. For bugs that are likely OS-specific and/or graphics-related, please also specify: -- Device (CPU model including architecture, e.g. x86, x86_64, ARM, etc.) +- Device (CPU model including architecture, e.g. x86_64, arm64, etc.) - GPU model (and the driver version in use if you know it) **Bug reports not including the required information may be closed at the diff --git a/SConstruct b/SConstruct index d0d03bd8dc..55ed3771ac 100644 --- a/SConstruct +++ b/SConstruct @@ -55,6 +55,7 @@ _helper_module("modules.modules_builders", "modules/modules_builders.py") import methods import glsl_builders import gles3_builders +from platform_methods import architectures, architecture_aliases if methods.get_cmdline_bool("tools", True): _helper_module("editor.editor_builders", "editor/editor_builders.py") @@ -161,12 +162,11 @@ if profile: opts = Variables(customs, ARGUMENTS) # Target build options -opts.Add("p", "Platform (alias for 'platform')", "") opts.Add("platform", "Target platform (%s)" % ("|".join(platform_list),), "") +opts.Add("p", "Platform (alias for 'platform')", "") opts.Add(BoolVariable("tools", "Build the tools (a.k.a. the Godot editor)", True)) opts.Add(EnumVariable("target", "Compilation target", "debug", ("debug", "release_debug", "release"))) -opts.Add("arch", "Platform-dependent architecture (arm/arm64/x86/x64/mips/...)", "") -opts.Add(EnumVariable("bits", "Target platform bits", "default", ("default", "32", "64"))) +opts.Add(EnumVariable("arch", "CPU architecture", "auto", ["auto"] + architectures, architecture_aliases)) opts.Add(EnumVariable("float", "Floating-point precision", "default", ("default", "32", "64"))) opts.Add(EnumVariable("optimize", "Optimization type", "speed", ("speed", "size", "none"))) opts.Add(BoolVariable("production", "Set defaults to build Godot for use in production", False)) @@ -502,12 +502,17 @@ if selected_platform in platform_list: # Platform specific flags flag_list = platform_flags[selected_platform] for f in flag_list: - if not (f[0] in ARGUMENTS): # allow command line to override platform flags + if not (f[0] in ARGUMENTS) or ARGUMENTS[f[0]] == "auto": # Allow command line to override platform flags env[f[0]] = f[1] # Must happen after the flags' definition, so that they can be used by platform detect detect.configure(env) + print( + 'Building for platform "%s", architecture "%s", %s, target "%s".' + % (selected_platform, env["arch"], "editor" if env["tools"] else "template", env["target"]) + ) + # Set our C and C++ standard requirements. # C++17 is required as we need guaranteed copy elision as per GH-36436. # Prepending to make it possible to override. @@ -693,13 +698,7 @@ if selected_platform in platform_list: ) suffix += ".debug" - if env["arch"] != "": - suffix += "." + env["arch"] - elif env["bits"] == "32": - suffix += ".32" - elif env["bits"] == "64": - suffix += ".64" - + suffix += "." + env["arch"] suffix += env.extra_suffix sys.path.remove(tmppath) diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp index 9cf7c9caba..d09697b951 100644 --- a/core/io/image_loader.cpp +++ b/core/io/image_loader.cpp @@ -44,7 +44,7 @@ bool ImageFormatLoader::recognize(const String &p_extension) const { return false; } -Error ImageLoader::load_image(String p_file, Ref<Image> p_image, Ref<FileAccess> p_custom, bool p_force_linear, float p_scale) { +Error ImageLoader::load_image(String p_file, Ref<Image> p_image, Ref<FileAccess> p_custom, uint32_t p_flags, float p_scale) { ERR_FAIL_COND_V_MSG(p_image.is_null(), ERR_INVALID_PARAMETER, "It's not a reference to a valid Image object."); Ref<FileAccess> f = p_custom; @@ -60,7 +60,7 @@ Error ImageLoader::load_image(String p_file, Ref<Image> p_image, Ref<FileAccess> if (!loader[i]->recognize(extension)) { continue; } - Error err = loader[i]->load_image(p_image, f, p_force_linear, p_scale); + Error err = loader[i]->load_image(p_image, f, p_flags, p_scale); if (err != OK) { ERR_PRINT("Error loading image: " + p_file); } @@ -152,7 +152,7 @@ Ref<Resource> ResourceFormatLoaderImage::load(const String &p_path, const String Ref<Image> image; image.instantiate(); - Error err = ImageLoader::loader[idx]->load_image(image, f, false, 1.0); + Error err = ImageLoader::loader[idx]->load_image(image, f); if (err != OK) { if (r_error) { diff --git a/core/io/image_loader.h b/core/io/image_loader.h index c91d382c25..cb64d2310e 100644 --- a/core/io/image_loader.h +++ b/core/io/image_loader.h @@ -44,11 +44,16 @@ class ImageFormatLoader { friend class ResourceFormatLoaderImage; protected: - virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> p_fileaccess, bool p_force_linear, float p_scale) = 0; + virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> p_fileaccess, uint32_t p_flags = (uint32_t)FLAG_NONE, float p_scale = 1.0) = 0; virtual void get_recognized_extensions(List<String> *p_extensions) const = 0; bool recognize(const String &p_extension) const; public: + enum LoaderFlags { + FLAG_NONE = 0, + FLAG_FORCE_LINEAR = 1, + }; + virtual ~ImageFormatLoader() {} }; @@ -58,7 +63,7 @@ class ImageLoader { protected: public: - static Error load_image(String p_file, Ref<Image> p_image, Ref<FileAccess> p_custom = Ref<FileAccess>(), bool p_force_linear = false, float p_scale = 1.0); + static Error load_image(String p_file, Ref<Image> p_image, Ref<FileAccess> p_custom = Ref<FileAccess>(), uint32_t p_flags = (uint32_t)ImageFormatLoader::FLAG_NONE, float p_scale = 1.0); static void get_recognized_extensions(List<String> *p_extensions); static ImageFormatLoader *recognize(const String &p_extension); diff --git a/doc/classes/CharacterBody2D.xml b/doc/classes/CharacterBody2D.xml index b0594b6409..2d169904f7 100644 --- a/doc/classes/CharacterBody2D.xml +++ b/doc/classes/CharacterBody2D.xml @@ -164,13 +164,13 @@ <member name="motion_mode" type="int" setter="set_motion_mode" getter="get_motion_mode" enum="CharacterBody2D.MotionMode" default="0"> Sets the motion mode which defines the behavior of [method move_and_slide]. See [enum MotionMode] constants for available modes. </member> - <member name="moving_platform_apply_velocity_on_leave" type="int" setter="set_moving_platform_apply_velocity_on_leave" getter="get_moving_platform_apply_velocity_on_leave" enum="CharacterBody2D.MovingPlatformApplyVelocityOnLeave" default="0"> - Sets the behavior to apply when you leave a moving platform. By default, to be physically accurate, when you leave the last platform velocity is applied. See [enum MovingPlatformApplyVelocityOnLeave] constants for available behavior. - </member> - <member name="moving_platform_floor_layers" type="int" setter="set_moving_platform_floor_layers" getter="get_moving_platform_floor_layers" default="4294967295"> + <member name="platform_floor_layers" type="int" setter="set_platform_floor_layers" getter="get_platform_floor_layers" default="4294967295"> Collision layers that will be included for detecting floor bodies that will act as moving platforms to be followed by the [CharacterBody2D]. By default, all floor bodies are detected and propagate their velocity. </member> - <member name="moving_platform_wall_layers" type="int" setter="set_moving_platform_wall_layers" getter="get_moving_platform_wall_layers" default="0"> + <member name="platform_on_leave" type="int" setter="set_platform_on_leave" getter="get_platform_on_leave" enum="CharacterBody2D.PlatformOnLeave" default="0"> + Sets the behavior to apply when you leave a moving platform. By default, to be physically accurate, when you leave the last platform velocity is applied. See [enum PlatformOnLeave] constants for available behavior. + </member> + <member name="platform_wall_layers" type="int" setter="set_platform_wall_layers" getter="get_platform_wall_layers" default="0"> Collision layers that will be included for detecting wall bodies that will act as moving platforms to be followed by the [CharacterBody2D]. By default, all wall bodies are ignored. </member> <member name="safe_margin" type="float" setter="set_safe_margin" getter="get_safe_margin" default="0.08"> @@ -199,13 +199,13 @@ <constant name="MOTION_MODE_FLOATING" value="1" enum="MotionMode"> Apply when there is no notion of floor or ceiling. All collisions will be reported as [code]on_wall[/code]. In this mode, when you slide, the speed will always be constant. This mode is suitable for top-down games. </constant> - <constant name="PLATFORM_VEL_ON_LEAVE_ALWAYS" value="0" enum="MovingPlatformApplyVelocityOnLeave"> + <constant name="PLATFORM_ON_LEAVE_ADD_VELOCITY" value="0" enum="PlatformOnLeave"> Add the last platform velocity to the [member velocity] when you leave a moving platform. </constant> - <constant name="PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY" value="1" enum="MovingPlatformApplyVelocityOnLeave"> + <constant name="PLATFORM_ON_LEAVE_ADD_UPWARD_VELOCITY" value="1" enum="PlatformOnLeave"> Add the last platform velocity to the [member velocity] when you leave a moving platform, but any downward motion is ignored. It's useful to keep full jump height even when the platform is moving down. </constant> - <constant name="PLATFORM_VEL_ON_LEAVE_NEVER" value="2" enum="MovingPlatformApplyVelocityOnLeave"> + <constant name="PLATFORM_ON_LEAVE_DO_NOTHING" value="2" enum="PlatformOnLeave"> Do nothing when leaving a platform. </constant> </constants> diff --git a/doc/classes/CharacterBody3D.xml b/doc/classes/CharacterBody3D.xml index 7efdeb19b1..cbcd6b3af7 100644 --- a/doc/classes/CharacterBody3D.xml +++ b/doc/classes/CharacterBody3D.xml @@ -149,13 +149,13 @@ <member name="motion_mode" type="int" setter="set_motion_mode" getter="get_motion_mode" enum="CharacterBody3D.MotionMode" default="0"> Sets the motion mode which defines the behavior of [method move_and_slide]. See [enum MotionMode] constants for available modes. </member> - <member name="moving_platform_apply_velocity_on_leave" type="int" setter="set_moving_platform_apply_velocity_on_leave" getter="get_moving_platform_apply_velocity_on_leave" enum="CharacterBody3D.MovingPlatformApplyVelocityOnLeave" default="0"> - Sets the behavior to apply when you leave a moving platform. By default, to be physically accurate, when you leave the last platform velocity is applied. See [enum MovingPlatformApplyVelocityOnLeave] constants for available behavior. - </member> - <member name="moving_platform_floor_layers" type="int" setter="set_moving_platform_floor_layers" getter="get_moving_platform_floor_layers" default="4294967295"> + <member name="platform_floor_layers" type="int" setter="set_platform_floor_layers" getter="get_platform_floor_layers" default="4294967295"> Collision layers that will be included for detecting floor bodies that will act as moving platforms to be followed by the [CharacterBody3D]. By default, all floor bodies are detected and propagate their velocity. </member> - <member name="moving_platform_wall_layers" type="int" setter="set_moving_platform_wall_layers" getter="get_moving_platform_wall_layers" default="0"> + <member name="platform_on_leave" type="int" setter="set_platform_on_leave" getter="get_platform_on_leave" enum="CharacterBody3D.PlatformOnLeave" default="0"> + Sets the behavior to apply when you leave a moving platform. By default, to be physically accurate, when you leave the last platform velocity is applied. See [enum PlatformOnLeave] constants for available behavior. + </member> + <member name="platform_wall_layers" type="int" setter="set_platform_wall_layers" getter="get_platform_wall_layers" default="0"> Collision layers that will be included for detecting wall bodies that will act as moving platforms to be followed by the [CharacterBody3D]. By default, all wall bodies are ignored. </member> <member name="safe_margin" type="float" setter="set_safe_margin" getter="get_safe_margin" default="0.001"> @@ -184,13 +184,13 @@ <constant name="MOTION_MODE_FLOATING" value="1" enum="MotionMode"> Apply when there is no notion of floor or ceiling. All collisions will be reported as [code]on_wall[/code]. In this mode, when you slide, the speed will always be constant. This mode is suitable for games without ground like space games. </constant> - <constant name="PLATFORM_VEL_ON_LEAVE_ALWAYS" value="0" enum="MovingPlatformApplyVelocityOnLeave"> + <constant name="PLATFORM_ON_LEAVE_ADD_VELOCITY" value="0" enum="PlatformOnLeave"> Add the last platform velocity to the [member velocity] when you leave a moving platform. </constant> - <constant name="PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY" value="1" enum="MovingPlatformApplyVelocityOnLeave"> + <constant name="PLATFORM_ON_LEAVE_ADD_UPWARD_VELOCITY" value="1" enum="PlatformOnLeave"> Add the last platform velocity to the [member velocity] when you leave a moving platform, but any downward motion is ignored. It's useful to keep full jump height even when the platform is moving down. </constant> - <constant name="PLATFORM_VEL_ON_LEAVE_NEVER" value="2" enum="MovingPlatformApplyVelocityOnLeave"> + <constant name="PLATFORM_ON_LEAVE_DO_NOTHING" value="2" enum="PlatformOnLeave"> Do nothing when leaving a platform. </constant> </constants> diff --git a/doc/classes/Skeleton3D.xml b/doc/classes/Skeleton3D.xml index 69b9988641..75f7a37752 100644 --- a/doc/classes/Skeleton3D.xml +++ b/doc/classes/Skeleton3D.xml @@ -20,15 +20,6 @@ Adds a bone, with name [param name]. [method get_bone_count] will become the bone index. </description> </method> - <method name="add_bone_child"> - <return type="void" /> - <param index="0" name="bone_idx" type="int" /> - <param index="1" name="child_bone_idx" type="int" /> - <description> - Takes the given bone pose/transform and converts it to a world transform, relative to the [Skeleton3D] node. - This is useful for using the bone transform in calculations with transforms from [Node3D]-based nodes. - </description> - </method> <method name="clear_bones"> <return type="void" /> <description> @@ -272,15 +263,6 @@ Binds the given Skin to the Skeleton. </description> </method> - <method name="remove_bone_child"> - <return type="void" /> - <param index="0" name="bone_idx" type="int" /> - <param index="1" name="child_bone_idx" type="int" /> - <description> - Removes the passed in child bone index, [param child_bone_idx], from the passed-in bone, [param bone_idx], if it exists. - [b]Note:[/b] This does not remove the child bone, but instead it removes the connection it has to the parent bone. - </description> - </method> <method name="reset_bone_pose"> <return type="void" /> <param index="0" name="bone_idx" type="int" /> @@ -294,14 +276,6 @@ Sets all bone poses to rests. </description> </method> - <method name="set_bone_children"> - <return type="void" /> - <param index="0" name="bone_idx" type="int" /> - <param index="1" name="bone_children" type="PackedInt32Array" /> - <description> - Sets the children for the passed in bone, [param bone_idx], to the passed-in array of bone indexes, [param bone_children]. - </description> - </method> <method name="set_bone_enabled"> <return type="void" /> <param index="0" name="bone_idx" type="int" /> diff --git a/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp index 1f40641b80..f4c87da9e9 100644 --- a/drivers/alsa/audio_driver_alsa.cpp +++ b/drivers/alsa/audio_driver_alsa.cpp @@ -168,9 +168,8 @@ Error AudioDriverALSA::init() { return ERR_CANT_OPEN; } - active = false; - thread_exited = false; - exit_thread = false; + active.clear(); + exit_thread.clear(); Error err = init_device(); if (err == OK) { @@ -183,11 +182,11 @@ Error AudioDriverALSA::init() { void AudioDriverALSA::thread_func(void *p_udata) { AudioDriverALSA *ad = static_cast<AudioDriverALSA *>(p_udata); - while (!ad->exit_thread) { + while (!ad->exit_thread.is_set()) { ad->lock(); ad->start_counting_ticks(); - if (!ad->active) { + if (!ad->active.is_set()) { for (uint64_t i = 0; i < ad->period_size * ad->channels; i++) { ad->samples_out.write[i] = 0; } @@ -203,7 +202,7 @@ void AudioDriverALSA::thread_func(void *p_udata) { int todo = ad->period_size; int total = 0; - while (todo && !ad->exit_thread) { + while (todo && !ad->exit_thread.is_set()) { int16_t *src = (int16_t *)ad->samples_out.ptr(); int wrote = snd_pcm_writei(ad->pcm_handle, (void *)(src + (total * ad->channels)), todo); @@ -222,8 +221,8 @@ void AudioDriverALSA::thread_func(void *p_udata) { wrote = snd_pcm_recover(ad->pcm_handle, wrote, 0); if (wrote < 0) { ERR_PRINT("ALSA: Failed and can't recover: " + String(snd_strerror(wrote))); - ad->active = false; - ad->exit_thread = true; + ad->active.clear(); + ad->exit_thread.set(); } } } @@ -241,8 +240,8 @@ void AudioDriverALSA::thread_func(void *p_udata) { err = ad->init_device(); if (err != OK) { - ad->active = false; - ad->exit_thread = true; + ad->active.clear(); + ad->exit_thread.set(); } } } @@ -250,12 +249,10 @@ void AudioDriverALSA::thread_func(void *p_udata) { ad->stop_counting_ticks(); ad->unlock(); } - - ad->thread_exited = true; } void AudioDriverALSA::start() { - active = true; + active.set(); } int AudioDriverALSA::get_mix_rate() const { @@ -327,7 +324,7 @@ void AudioDriverALSA::finish_device() { } void AudioDriverALSA::finish() { - exit_thread = true; + exit_thread.set(); thread.wait_to_finish(); finish_device(); diff --git a/drivers/alsa/audio_driver_alsa.h b/drivers/alsa/audio_driver_alsa.h index 3f9d9b33fb..fa1dba38ed 100644 --- a/drivers/alsa/audio_driver_alsa.h +++ b/drivers/alsa/audio_driver_alsa.h @@ -35,6 +35,7 @@ #include "core/os/mutex.h" #include "core/os/thread.h" +#include "core/templates/safe_refcount.h" #include "servers/audio_server.h" #include "asound-so_wrap.h" @@ -64,9 +65,8 @@ class AudioDriverALSA : public AudioDriver { snd_pcm_uframes_t period_size; int channels = 0; - bool active = false; - bool thread_exited = false; - mutable bool exit_thread = false; + SafeFlag active; + SafeFlag exit_thread; public: const char *get_name() const { diff --git a/drivers/alsamidi/midi_driver_alsamidi.cpp b/drivers/alsamidi/midi_driver_alsamidi.cpp index c334146dd2..d2a0076023 100644 --- a/drivers/alsamidi/midi_driver_alsamidi.cpp +++ b/drivers/alsamidi/midi_driver_alsamidi.cpp @@ -79,7 +79,7 @@ void MIDIDriverALSAMidi::thread_func(void *p_udata) { int expected_size = 255; int bytes = 0; - while (!md->exit_thread) { + while (!md->exit_thread.is_set()) { int ret; md->lock(); @@ -149,14 +149,14 @@ Error MIDIDriverALSAMidi::open() { } snd_device_name_free_hint(hints); - exit_thread = false; + exit_thread.clear(); thread.start(MIDIDriverALSAMidi::thread_func, this); return OK; } void MIDIDriverALSAMidi::close() { - exit_thread = true; + exit_thread.set(); thread.wait_to_finish(); for (int i = 0; i < connected_inputs.size(); i++) { @@ -193,7 +193,7 @@ PackedStringArray MIDIDriverALSAMidi::get_connected_inputs() { } MIDIDriverALSAMidi::MIDIDriverALSAMidi() { - exit_thread = false; + exit_thread.clear(); } MIDIDriverALSAMidi::~MIDIDriverALSAMidi() { diff --git a/drivers/alsamidi/midi_driver_alsamidi.h b/drivers/alsamidi/midi_driver_alsamidi.h index b0fa8c297a..ac3530b1b2 100644 --- a/drivers/alsamidi/midi_driver_alsamidi.h +++ b/drivers/alsamidi/midi_driver_alsamidi.h @@ -36,6 +36,7 @@ #include "core/os/midi_driver.h" #include "core/os/mutex.h" #include "core/os/thread.h" +#include "core/templates/safe_refcount.h" #include "core/templates/vector.h" #include "../alsa/asound-so_wrap.h" @@ -47,7 +48,7 @@ class MIDIDriverALSAMidi : public MIDIDriver { Vector<snd_rawmidi_t *> connected_inputs; - bool exit_thread; + SafeFlag exit_thread; static void thread_func(void *p_udata); diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp index 51fb1f99e0..1db85e2a60 100644 --- a/drivers/coreaudio/audio_driver_coreaudio.cpp +++ b/drivers/coreaudio/audio_driver_coreaudio.cpp @@ -215,6 +215,7 @@ OSStatus AudioDriverCoreAudio::input_callback(void *inRefCon, } ad->lock(); + ad->start_counting_ticks(); AudioBufferList bufferList; bufferList.mNumberBuffers = 1; @@ -237,6 +238,7 @@ OSStatus AudioDriverCoreAudio::input_callback(void *inRefCon, ERR_PRINT("AudioUnitRender failed, code: " + itos(result)); } + ad->stop_counting_ticks(); ad->unlock(); return result; diff --git a/drivers/png/SCsub b/drivers/png/SCsub index 39d296e7cf..ad7aaf1ee8 100644 --- a/drivers/png/SCsub +++ b/drivers/png/SCsub @@ -37,7 +37,7 @@ if env["builtin_libpng"]: import os # Enable ARM NEON instructions on 32-bit Android to compile more optimized code. - use_neon = "android_arch" in env and env["android_arch"] == "armv7" and os.name != "nt" + use_neon = env["platform"] == "android" and env["arch"] == "arm32" and os.name != "nt" if use_neon: env_png.Append(CPPDEFINES=[("PNG_ARM_NEON_OPT", 2)]) else: diff --git a/drivers/png/image_loader_png.cpp b/drivers/png/image_loader_png.cpp index 917bfec574..8d2f8a7ed6 100644 --- a/drivers/png/image_loader_png.cpp +++ b/drivers/png/image_loader_png.cpp @@ -36,7 +36,7 @@ #include <string.h> -Error ImageLoaderPNG::load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_force_linear, float p_scale) { +Error ImageLoaderPNG::load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale) { const uint64_t buffer_size = f->get_length(); Vector<uint8_t> file_buffer; Error err = file_buffer.resize(buffer_size); @@ -48,7 +48,7 @@ Error ImageLoaderPNG::load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_f f->get_buffer(writer, buffer_size); } const uint8_t *reader = file_buffer.ptr(); - return PNGDriverCommon::png_to_image(reader, buffer_size, p_force_linear, p_image); + return PNGDriverCommon::png_to_image(reader, buffer_size, p_flags & FLAG_FORCE_LINEAR, p_image); } void ImageLoaderPNG::get_recognized_extensions(List<String> *p_extensions) const { diff --git a/drivers/png/image_loader_png.h b/drivers/png/image_loader_png.h index 9bcfb720d3..91c3c8925f 100644 --- a/drivers/png/image_loader_png.h +++ b/drivers/png/image_loader_png.h @@ -40,7 +40,7 @@ private: static Ref<Image> load_mem_png(const uint8_t *p_png, int p_size); public: - virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_force_linear, float p_scale); + virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale); virtual void get_recognized_extensions(List<String> *p_extensions) const; ImageLoaderPNG(); }; diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp index b18d383119..b25cf1d5b4 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp +++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp @@ -285,9 +285,8 @@ Error AudioDriverPulseAudio::init() { return ERR_CANT_OPEN; } - active = false; - thread_exited = false; - exit_thread = false; + active.clear(); + exit_thread.clear(); mix_rate = GLOBAL_GET("audio/driver/mix_rate"); @@ -384,7 +383,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) { size_t avail_bytes = 0; uint64_t default_device_msec = OS::get_singleton()->get_ticks_msec(); - while (!ad->exit_thread) { + while (!ad->exit_thread.is_set()) { size_t read_bytes = 0; size_t written_bytes = 0; @@ -392,7 +391,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) { ad->lock(); ad->start_counting_ticks(); - if (!ad->active) { + if (!ad->active.is_set()) { ad->samples_out.fill(0); } else { ad->audio_server_process(ad->buffer_frames, ad->samples_in.ptrw()); @@ -462,8 +461,8 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) { err = ad->init_device(); if (err != OK) { - ad->active = false; - ad->exit_thread = true; + ad->active.clear(); + ad->exit_thread.set(); break; } } @@ -501,8 +500,8 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) { Error err = ad->init_device(); if (err != OK) { ERR_PRINT("PulseAudio: init_device error"); - ad->active = false; - ad->exit_thread = true; + ad->active.clear(); + ad->exit_thread.set(); break; } @@ -555,8 +554,8 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) { err = ad->capture_init_device(); if (err != OK) { - ad->active = false; - ad->exit_thread = true; + ad->active.clear(); + ad->exit_thread.set(); break; } } @@ -571,12 +570,10 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) { OS::get_singleton()->delay_usec(1000); } } - - ad->thread_exited = true; } void AudioDriverPulseAudio::start() { - active = true; + active.set(); } int AudioDriverPulseAudio::get_mix_rate() const { @@ -661,7 +658,7 @@ void AudioDriverPulseAudio::finish() { return; } - exit_thread = true; + exit_thread.set(); thread.wait_to_finish(); finish_device(); diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.h b/drivers/pulseaudio/audio_driver_pulseaudio.h index 27c684578e..85e328b49f 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.h +++ b/drivers/pulseaudio/audio_driver_pulseaudio.h @@ -35,6 +35,7 @@ #include "core/os/mutex.h" #include "core/os/thread.h" +#include "core/templates/safe_refcount.h" #include "servers/audio_server.h" #include "pulse-so_wrap.h" @@ -70,9 +71,8 @@ class AudioDriverPulseAudio : public AudioDriver { PackedStringArray pa_devices; PackedStringArray pa_rec_devices; - bool active = false; - bool thread_exited = false; - mutable bool exit_thread = false; + SafeFlag active; + SafeFlag exit_thread; float latency = 0; diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp index 8f5e35b251..fb90b776cf 100644 --- a/drivers/wasapi/audio_driver_wasapi.cpp +++ b/drivers/wasapi/audio_driver_wasapi.cpp @@ -501,11 +501,11 @@ Error AudioDriverWASAPI::init_capture_device(bool reinit) { } Error AudioDriverWASAPI::audio_device_finish(AudioDeviceWASAPI *p_device) { - if (p_device->active) { + if (p_device->active.is_set()) { if (p_device->audio_client) { p_device->audio_client->Stop(); } - p_device->active = false; + p_device->active.clear(); } SAFE_RELEASE(p_device->audio_client) @@ -533,8 +533,7 @@ Error AudioDriverWASAPI::init() { ERR_PRINT("WASAPI: init_render_device error"); } - exit_thread = false; - thread_exited = false; + exit_thread.clear(); thread.start(thread_func, this); @@ -684,7 +683,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) { uint32_t avail_frames = 0; uint32_t write_ofs = 0; - while (!ad->exit_thread) { + while (!ad->exit_thread.is_set()) { uint32_t read_frames = 0; uint32_t written_frames = 0; @@ -692,7 +691,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) { ad->lock(); ad->start_counting_ticks(); - if (ad->audio_output.active) { + if (ad->audio_output.active.is_set()) { ad->audio_server_process(ad->buffer_frames, ad->samples_in.ptrw()); } else { for (int i = 0; i < ad->samples_in.size(); i++) { @@ -758,7 +757,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) { } } else { ERR_PRINT("WASAPI: Get buffer error"); - ad->exit_thread = true; + ad->exit_thread.set(); } } } else if (hr == AUDCLNT_E_DEVICE_INVALIDATED) { @@ -807,7 +806,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) { write_ofs = 0; } - if (ad->audio_input.active) { + if (ad->audio_input.active.is_set()) { UINT32 packet_length = 0; BYTE *data; UINT32 num_frames_available; @@ -886,8 +885,6 @@ void AudioDriverWASAPI::thread_func(void *p_udata) { OS::get_singleton()->delay_usec(1000); } } - - ad->thread_exited = true; } void AudioDriverWASAPI::start() { @@ -896,7 +893,7 @@ void AudioDriverWASAPI::start() { if (hr != S_OK) { ERR_PRINT("WASAPI: Start failed"); } else { - audio_output.active = true; + audio_output.active.set(); } } } @@ -910,7 +907,7 @@ void AudioDriverWASAPI::unlock() { } void AudioDriverWASAPI::finish() { - exit_thread = true; + exit_thread.set(); thread.wait_to_finish(); finish_capture_device(); @@ -924,19 +921,19 @@ Error AudioDriverWASAPI::capture_start() { return err; } - if (audio_input.active) { + if (audio_input.active.is_set()) { return FAILED; } audio_input.audio_client->Start(); - audio_input.active = true; + audio_input.active.set(); return OK; } Error AudioDriverWASAPI::capture_stop() { - if (audio_input.active) { + if (audio_input.active.is_set()) { audio_input.audio_client->Stop(); - audio_input.active = false; + audio_input.active.clear(); return OK; } diff --git a/drivers/wasapi/audio_driver_wasapi.h b/drivers/wasapi/audio_driver_wasapi.h index d71e2e914b..c30a54c042 100644 --- a/drivers/wasapi/audio_driver_wasapi.h +++ b/drivers/wasapi/audio_driver_wasapi.h @@ -35,6 +35,7 @@ #include "core/os/mutex.h" #include "core/os/thread.h" +#include "core/templates/safe_refcount.h" #include "servers/audio_server.h" #include <audioclient.h> @@ -48,7 +49,7 @@ class AudioDriverWASAPI : public AudioDriver { IAudioClient *audio_client = nullptr; IAudioRenderClient *render_client = nullptr; IAudioCaptureClient *capture_client = nullptr; - bool active = false; + SafeFlag active; WORD format_tag = 0; WORD bits_per_sample = 0; @@ -76,8 +77,7 @@ class AudioDriverWASAPI : public AudioDriver { float real_latency = 0.0; bool using_audio_client_3 = false; - bool thread_exited = false; - mutable bool exit_thread = false; + SafeFlag exit_thread; static _FORCE_INLINE_ void write_sample(WORD format_tag, int bits_per_sample, BYTE *buffer, int i, int32_t sample); static _FORCE_INLINE_ int32_t read_sample(WORD format_tag, int bits_per_sample, BYTE *buffer, int i); diff --git a/drivers/xaudio2/audio_driver_xaudio2.cpp b/drivers/xaudio2/audio_driver_xaudio2.cpp index c32c7cf1e5..6c48c1a844 100644 --- a/drivers/xaudio2/audio_driver_xaudio2.cpp +++ b/drivers/xaudio2/audio_driver_xaudio2.cpp @@ -38,9 +38,8 @@ const char *AudioDriverXAudio2::get_name() const { } Error AudioDriverXAudio2::init() { - active = false; - thread_exited = false; - exit_thread = false; + active.clear(); + exit_thread.clear(); pcm_open = false; samples_in = nullptr; @@ -86,17 +85,19 @@ Error AudioDriverXAudio2::init() { void AudioDriverXAudio2::thread_func(void *p_udata) { AudioDriverXAudio2 *ad = static_cast<AudioDriverXAudio2 *>(p_udata); - while (!ad->exit_thread) { - if (!ad->active) { + while (!ad->exit_thread.is_set()) { + if (!ad->active.is_set()) { for (int i = 0; i < AUDIO_BUFFERS; i++) { ad->xaudio_buffer[i].Flags = XAUDIO2_END_OF_STREAM; } } else { ad->lock(); + ad->start_counting_ticks(); ad->audio_server_process(ad->buffer_size, ad->samples_in); + ad->stop_counting_ticks(); ad->unlock(); for (unsigned int i = 0; i < ad->buffer_size * ad->channels; i++) { @@ -117,12 +118,10 @@ void AudioDriverXAudio2::thread_func(void *p_udata) { } } } - - ad->thread_exited = true; } void AudioDriverXAudio2::start() { - active = true; + active.set(); HRESULT hr = source_voice->Start(0); ERR_FAIL_COND_MSG(hr != S_OK, "Error starting XAudio2 driver. Error code: " + itos(hr) + "."); } @@ -154,7 +153,7 @@ void AudioDriverXAudio2::unlock() { } void AudioDriverXAudio2::finish() { - exit_thread = true; + exit_thread.set(); thread.wait_to_finish(); if (source_voice) { diff --git a/drivers/xaudio2/audio_driver_xaudio2.h b/drivers/xaudio2/audio_driver_xaudio2.h index 81432ceb8e..0f64d54a1f 100644 --- a/drivers/xaudio2/audio_driver_xaudio2.h +++ b/drivers/xaudio2/audio_driver_xaudio2.h @@ -33,6 +33,7 @@ #include "core/os/mutex.h" #include "core/os/thread.h" +#include "core/templates/safe_refcount.h" #include "servers/audio_server.h" #include <mmsystem.h> @@ -77,9 +78,8 @@ class AudioDriverXAudio2 : public AudioDriver { int channels = 0; - bool active = false; - bool thread_exited = false; - mutable bool exit_thread = false; + SafeFlag active; + SafeFlag exit_thread; bool pcm_open = false; WAVEFORMATEX wave_format = { 0 }; diff --git a/editor/action_map_editor.cpp b/editor/action_map_editor.cpp index 462f314471..648e950fd4 100644 --- a/editor/action_map_editor.cpp +++ b/editor/action_map_editor.cpp @@ -1061,6 +1061,9 @@ void ActionMapEditor::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { action_list_search->set_right_icon(get_theme_icon(SNAME("Search"), SNAME("EditorIcons"))); + if (!actions_cache.is_empty()) { + update_action_list(); + } } break; } } diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp index b301bbf0f9..ed83535421 100644 --- a/editor/import/resource_importer_layered_texture.cpp +++ b/editor/import/resource_importer_layered_texture.cpp @@ -327,7 +327,7 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const Ref<Image> image; image.instantiate(); - Error err = ImageLoader::load_image(p_source_file, image, nullptr, false, 1.0); + Error err = ImageLoader::load_image(p_source_file, image); if (err != OK) { return err; } diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp index 0eed6184c0..17b94ec706 100644 --- a/editor/import/resource_importer_texture.cpp +++ b/editor/import/resource_importer_texture.cpp @@ -409,11 +409,26 @@ void ResourceImporterTexture::_save_ctex(const Ref<Image> &p_image, const String } Error ResourceImporterTexture::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { + // Parse import options. + int32_t loader_flags = ImageFormatLoader::FLAG_NONE; + + // Compression. CompressMode compress_mode = CompressMode(int(p_options["compress/mode"])); const float lossy = p_options["compress/lossy_quality"]; const int pack_channels = p_options["compress/channel_pack"]; + const int normal = p_options["compress/normal_map"]; + const int hdr_compression = p_options["compress/hdr_compression"]; + const int bptc_ldr = p_options["compress/bptc_ldr"]; + + // Mipmaps. const bool mipmaps = p_options["mipmaps/generate"]; const uint32_t mipmap_limit = mipmaps ? uint32_t(p_options["mipmaps/limit"]) : uint32_t(-1); + + // Roughness. + const int roughness = p_options["roughness/mode"]; + const String normal_map = p_options["roughness/src_normal"]; + + // Processing. const bool fix_alpha_border = p_options["process/fix_alpha_border"]; const bool premult_alpha = p_options["process/premult_alpha"]; const bool normal_map_invert_y = p_options["process/normal_map_invert_y"]; @@ -421,29 +436,29 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String const bool stream = false; const int size_limit = p_options["process/size_limit"]; const bool hdr_as_srgb = p_options["process/hdr_as_srgb"]; + if (hdr_as_srgb) { + loader_flags |= ImageFormatLoader::FLAG_FORCE_LINEAR; + } const bool hdr_clamp_exposure = p_options["process/hdr_clamp_exposure"]; - const int normal = p_options["compress/normal_map"]; - const int hdr_compression = p_options["compress/hdr_compression"]; - const int bptc_ldr = p_options["compress/bptc_ldr"]; - const int roughness = p_options["roughness/mode"]; - const String normal_map = p_options["roughness/src_normal"]; + float scale = 1.0; + // SVG-specific options. if (p_options.has("svg/scale")) { scale = p_options["svg/scale"]; } Ref<Image> normal_image; Image::RoughnessChannel roughness_channel = Image::ROUGHNESS_CHANNEL_R; - if (mipmaps && roughness > 1 && FileAccess::exists(normal_map)) { normal_image.instantiate(); if (ImageLoader::load_image(normal_map, normal_image) == OK) { roughness_channel = Image::RoughnessChannel(roughness - 2); } } + Ref<Image> image; image.instantiate(); - Error err = ImageLoader::load_image(p_source_file, image, nullptr, hdr_as_srgb, scale); + Error err = ImageLoader::load_image(p_source_file, image, nullptr, loader_flags, scale); if (err != OK) { return err; } diff --git a/methods.py b/methods.py index c02517d137..9b60d4251f 100644 --- a/methods.py +++ b/methods.py @@ -540,7 +540,7 @@ def detect_visual_c_compiler_version(tools_env): # and not scons setup environment (env)... so make sure you call the right environment on it or it will fail to detect # the proper vc version that will be called - # There is no flag to give to visual c compilers to set the architecture, i.e. scons bits argument (32,64,ARM etc) + # There is no flag to give to visual c compilers to set the architecture, i.e. scons arch argument (x86_32, x86_64, arm64, etc.). # There are many different cl.exe files that are run, and each one compiles & links to a different architecture # As far as I know, the only way to figure out what compiler will be run when Scons calls cl.exe via Program() # is to check the PATH variable and figure out which one will be called first. Code below does that and returns: diff --git a/modules/bmp/image_loader_bmp.cpp b/modules/bmp/image_loader_bmp.cpp index 8813c3827a..ae03abca50 100644 --- a/modules/bmp/image_loader_bmp.cpp +++ b/modules/bmp/image_loader_bmp.cpp @@ -200,7 +200,7 @@ Error ImageLoaderBMP::convert_to_image(Ref<Image> p_image, return err; } -Error ImageLoaderBMP::load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_force_linear, float p_scale) { +Error ImageLoaderBMP::load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale) { bmp_header_s bmp_header; Error err = ERR_INVALID_DATA; diff --git a/modules/bmp/image_loader_bmp.h b/modules/bmp/image_loader_bmp.h index 63dee0a969..cf8346ecad 100644 --- a/modules/bmp/image_loader_bmp.h +++ b/modules/bmp/image_loader_bmp.h @@ -83,7 +83,7 @@ protected: const bmp_header_s &p_header); public: - virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_force_linear, float p_scale); + virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale); virtual void get_recognized_extensions(List<String> *p_extensions) const; ImageLoaderBMP(); }; diff --git a/modules/denoise/config.py b/modules/denoise/config.py index 521115dae5..350839651a 100644 --- a/modules/denoise/config.py +++ b/modules/denoise/config.py @@ -5,14 +5,7 @@ def can_build(env, platform): # as doing lightmap generation and denoising on Android or HTML5 # would be a bit far-fetched. desktop_platforms = ["linuxbsd", "macos", "windows"] - supported_arch = env["bits"] == "64" - if env["arch"] == "arm64": - supported_arch = False - if env["arch"].startswith("ppc"): - supported_arch = False - if env["arch"].startswith("rv"): - supported_arch = False - return env["tools"] and platform in desktop_platforms and supported_arch + return env["tools"] and platform in desktop_platforms and env["arch"] == "x86_64" def configure(env): diff --git a/modules/hdr/image_loader_hdr.cpp b/modules/hdr/image_loader_hdr.cpp index eca689e87a..e7c6fe592d 100644 --- a/modules/hdr/image_loader_hdr.cpp +++ b/modules/hdr/image_loader_hdr.cpp @@ -33,7 +33,7 @@ #include "core/os/os.h" #include "core/string/print_string.h" -Error ImageLoaderHDR::load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_force_linear, float p_scale) { +Error ImageLoaderHDR::load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale) { String header = f->get_token(); ERR_FAIL_COND_V_MSG(header != "#?RADIANCE" && header != "#?RGBE", ERR_FILE_UNRECOGNIZED, "Unsupported header information in HDR: " + header + "."); @@ -131,7 +131,7 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_f ptr[1] * exp / 255.0, ptr[2] * exp / 255.0); - if (p_force_linear) { + if (p_flags & FLAG_FORCE_LINEAR) { c = c.srgb_to_linear(); } diff --git a/modules/hdr/image_loader_hdr.h b/modules/hdr/image_loader_hdr.h index 16c0816562..1bff05129b 100644 --- a/modules/hdr/image_loader_hdr.h +++ b/modules/hdr/image_loader_hdr.h @@ -35,7 +35,7 @@ class ImageLoaderHDR : public ImageFormatLoader { public: - virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_force_linear, float p_scale); + virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale); virtual void get_recognized_extensions(List<String> *p_extensions) const; ImageLoaderHDR(); }; diff --git a/modules/jpg/image_loader_jpegd.cpp b/modules/jpg/image_loader_jpegd.cpp index 0e03fa65c8..3e138bf633 100644 --- a/modules/jpg/image_loader_jpegd.cpp +++ b/modules/jpg/image_loader_jpegd.cpp @@ -104,7 +104,7 @@ Error jpeg_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p return OK; } -Error ImageLoaderJPG::load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_force_linear, float p_scale) { +Error ImageLoaderJPG::load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale) { Vector<uint8_t> src_image; uint64_t src_image_len = f->get_length(); ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT); diff --git a/modules/jpg/image_loader_jpegd.h b/modules/jpg/image_loader_jpegd.h index 6d631446e7..caa0461d05 100644 --- a/modules/jpg/image_loader_jpegd.h +++ b/modules/jpg/image_loader_jpegd.h @@ -35,7 +35,7 @@ class ImageLoaderJPG : public ImageFormatLoader { public: - virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_force_linear, float p_scale); + virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale); virtual void get_recognized_extensions(List<String> *p_extensions) const; ImageLoaderJPG(); }; diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py index 556c8e1563..8141bc2422 100644 --- a/modules/mono/build_scripts/mono_configure.py +++ b/modules/mono/build_scripts/mono_configure.py @@ -18,7 +18,7 @@ def configure(env, env_mono): # is_android = env["platform"] == "android" # is_javascript = env["platform"] == "javascript" # is_ios = env["platform"] == "ios" - # is_ios_sim = is_ios and env["arch"] in ["x86", "x86_64"] + # is_ios_sim = is_ios and env["arch"] in ["x86_32", "x86_64"] tools_enabled = env["tools"] @@ -82,7 +82,7 @@ def find_dotnet_app_host_dir(env): dotnet_root = env["dotnet_root"] if not dotnet_root: - dotnet_cmd = find_executable("dotnet") + dotnet_cmd = find_dotnet_executable(env["arch"]) if dotnet_cmd: sdk_path = find_dotnet_sdk(dotnet_cmd, dotnet_version) if sdk_path: @@ -128,26 +128,22 @@ def find_dotnet_app_host_dir(env): def determine_runtime_identifier(env): + # The keys are Godot's names, the values are the Microsoft's names. + # List: https://docs.microsoft.com/en-us/dotnet/core/rid-catalog names_map = { "windows": "win", "macos": "osx", "linuxbsd": "linux", } - - # .NET RID architectures: x86, x64, arm, or arm64 - + arch_map = { + "x86_64": "x64", + "x86_32": "x86", + "arm64": "arm64", + "arm32": "arm", + } platform = env["platform"] - if is_desktop(platform): - if env["arch"] in ["arm", "arm32"]: - rid = "arm" - elif env["arch"] == "arm64": - rid = "arm64" - else: - bits = env["bits"] - bit_arch_map = {"64": "x64", "32": "x86"} - rid = bit_arch_map[bits] - return "%s-%s" % (names_map[platform], rid) + return "%s-%s" % (names_map[platform], arch_map[env["arch"]]) else: raise NotImplementedError() @@ -185,6 +181,35 @@ def find_app_host_version(dotnet_cmd, search_version_str): return "" +def find_dotnet_arch(dotnet_cmd): + import subprocess + + try: + env = dict(os.environ, DOTNET_CLI_UI_LANGUAGE="en-US") + lines = subprocess.check_output([dotnet_cmd, "--info"], env=env).splitlines() + + for line_bytes in lines: + line = line_bytes.decode("utf-8") + + parts = line.split(":", 1) + if len(parts) < 2: + continue + + arch_str = parts[0].strip() + if arch_str != "Architecture": + continue + + arch_value = parts[1].strip() + arch_map = {"x64": "x86_64", "x86": "x86_32", "arm64": "arm64", "arm32": "arm32"} + return arch_map[arch_value] + except (subprocess.CalledProcessError, OSError) as e: + import sys + + print(e, file=sys.stderr) + + return "" + + def find_dotnet_sdk(dotnet_cmd, search_version_str): import subprocess from distutils.version import LooseVersion @@ -247,24 +272,36 @@ def find_dotnet_cli_rid(dotnet_cmd): ENV_PATH_SEP = ";" if os.name == "nt" else ":" -def find_executable(name): +def find_dotnet_executable(arch): is_windows = os.name == "nt" windows_exts = os.environ["PATHEXT"].split(ENV_PATH_SEP) if is_windows else None path_dirs = os.environ["PATH"].split(ENV_PATH_SEP) search_dirs = path_dirs + [os.getcwd()] # cwd is last in the list + for dir in path_dirs: + search_dirs += [ + os.path.join(dir, "x64"), + os.path.join(dir, "x86"), + os.path.join(dir, "arm64"), + os.path.join(dir, "arm32"), + ] # search subfolders for cross compiling + for dir in search_dirs: - path = os.path.join(dir, name) + path = os.path.join(dir, "dotnet") if is_windows: for extension in windows_exts: path_with_ext = path + extension if os.path.isfile(path_with_ext) and os.access(path_with_ext, os.X_OK): - return path_with_ext + sdk_arch = find_dotnet_arch(path_with_ext) + if sdk_arch == arch or arch == "": + return path_with_ext else: if os.path.isfile(path) and os.access(path, os.X_OK): - return path + sdk_arch = find_dotnet_arch(path) + if sdk_arch == arch or arch == "": + return path return "" diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs index 8aec1bd656..fc325fc25b 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs @@ -75,8 +75,17 @@ namespace GodotTools.Export } else { - string bits = features.Contains("64") ? "64" : features.Contains("32") ? "32" : null; - CompileAssembliesForDesktop(exporter, platform, isDebug, bits, aotOpts, aotTempDir, outputDataDir, assembliesPrepared, bclDir); + string arch = ""; + if (features.Contains("x86_64")) { + arch = "x86_64"; + } else if (features.Contains("x86_32")) { + arch = "x86_32"; + } else if (features.Contains("arm64")) { + arch = "arm64"; + } else if (features.Contains("arm32")) { + arch = "arm32"; + } + CompileAssembliesForDesktop(exporter, platform, isDebug, arch, aotOpts, aotTempDir, outputDataDir, assembliesPrepared, bclDir); } } @@ -112,7 +121,7 @@ namespace GodotTools.Export } } - public static void CompileAssembliesForDesktop(ExportPlugin exporter, string platform, bool isDebug, string bits, AotOptions aotOpts, string aotTempDir, string outputDataDir, IDictionary<string, string> assemblies, string bclDir) + public static void CompileAssembliesForDesktop(ExportPlugin exporter, string platform, bool isDebug, string arch, AotOptions aotOpts, string aotTempDir, string outputDataDir, IDictionary<string, string> assemblies, string bclDir) { foreach (var assembly in assemblies) { @@ -126,9 +135,9 @@ namespace GodotTools.Export string outputFileName = assemblyName + ".dll" + outputFileExtension; string tempOutputFilePath = Path.Combine(aotTempDir, outputFileName); - var compilerArgs = GetAotCompilerArgs(platform, isDebug, bits, aotOpts, assemblyPath, tempOutputFilePath); + var compilerArgs = GetAotCompilerArgs(platform, isDebug, arch, aotOpts, assemblyPath, tempOutputFilePath); - string compilerDirPath = GetMonoCrossDesktopDirName(platform, bits); + string compilerDirPath = GetMonoCrossDesktopDirName(platform, arch); ExecuteCompiler(FindCrossCompiler(compilerDirPath), compilerArgs, bclDir); @@ -432,9 +441,9 @@ MONO_AOT_MODE_LAST = 1000, var androidToolPrefixes = new Dictionary<string, string> { - ["armeabi-v7a"] = "arm-linux-androideabi-", - ["arm64-v8a"] = "aarch64-linux-android-", - ["x86"] = "i686-linux-android-", + ["arm32"] = "arm-linux-androideabi-", + ["arm64"] = "aarch64-linux-android-", + ["x86_32"] = "i686-linux-android-", ["x86_64"] = "x86_64-linux-android-" }; @@ -547,9 +556,9 @@ MONO_AOT_MODE_LAST = 1000, { var androidAbis = new[] { - "armeabi-v7a", - "arm64-v8a", - "x86", + "arm32", + "arm64", + "x86_32", "x86_64" }; @@ -560,9 +569,9 @@ MONO_AOT_MODE_LAST = 1000, { var abiArchs = new Dictionary<string, string> { - ["armeabi-v7a"] = "armv7", - ["arm64-v8a"] = "aarch64-v8a", - ["x86"] = "i686", + ["arm32"] = "armv7", + ["arm64"] = "aarch64-v8a", + ["x86_32"] = "i686", ["x86_64"] = "x86_64" }; @@ -571,30 +580,25 @@ MONO_AOT_MODE_LAST = 1000, return $"{arch}-linux-android"; } - private static string GetMonoCrossDesktopDirName(string platform, string bits) + private static string GetMonoCrossDesktopDirName(string platform, string arch) { switch (platform) { case OS.Platforms.Windows: case OS.Platforms.UWP: { - string arch = bits == "64" ? "x86_64" : "i686"; return $"windows-{arch}"; } case OS.Platforms.MacOS: { - Debug.Assert(bits == null || bits == "64"); - string arch = "x86_64"; return $"{platform}-{arch}"; } case OS.Platforms.LinuxBSD: { - string arch = bits == "64" ? "x86_64" : "i686"; return $"linux-{arch}"; } case OS.Platforms.Haiku: { - string arch = bits == "64" ? "x86_64" : "i686"; return $"{platform}-{arch}"; } default: diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs index 76f0f0b784..651922d019 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs @@ -15,6 +15,9 @@ namespace GodotTools.Utils [SuppressMessage("ReSharper", "InconsistentNaming")] public static class OS { + /// <summary> + /// Display names for the OS platforms. + /// </summary> private static class Names { public const string Windows = "Windows"; @@ -30,6 +33,9 @@ namespace GodotTools.Utils public const string HTML5 = "HTML5"; } + /// <summary> + /// Godot platform identifiers. + /// </summary> public static class Platforms { public const string Windows = "windows"; @@ -42,6 +48,10 @@ namespace GodotTools.Utils public const string HTML5 = "javascript"; } + /// <summary> + /// OS name part of the .NET runtime identifier (RID). + /// See https://docs.microsoft.com/en-us/dotnet/core/rid-catalog. + /// </summary> public static class DotNetOS { public const string Win = "win"; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs index 9348cc1d00..9e7da7757a 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs @@ -189,8 +189,6 @@ namespace Godot /// Pushes an error message to Godot's built-in debugger and to the OS terminal. /// /// Note: Errors printed this way will not pause project execution. - /// To print an error message and pause project execution in debug builds, - /// use [code]assert(false, "test error")[/code] instead. /// </summary> /// <example> /// <code> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs index 08beff8104..41a0dd871c 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs @@ -754,9 +754,10 @@ namespace Godot } /// <summary> - /// Returns the [code]value[/code] wrapped between [code]0[/code] and the [code]length[/code]. - /// If the limit is reached, the next value the function returned is decreased to the [code]0[/code] side or increased to the [code]length[/code] side (like a triangle wave). - /// If [code]length[/code] is less than zero, it becomes positive. + /// Returns the <paramref name="value"/> wrapped between <c>0</c> and the <paramref name="length"/>. + /// If the limit is reached, the next value the function returned is decreased to the <c>0</c> side + /// or increased to the <paramref name="length"/> side (like a triangle wave). + /// If <paramref name="length"/> is less than zero, it becomes positive. /// </summary> /// <param name="value">The value to pingpong.</param> /// <param name="length">The maximum value of the function.</param> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs index b85a105a0b..d62cb6b0fa 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs @@ -39,22 +39,22 @@ namespace Godot } /// <summary> - /// The projections's X column. Also accessible by using the index position <c>[0]</c>. + /// The projection's X column. Also accessible by using the index position <c>[0]</c>. /// </summary> public Vector4 x; /// <summary> - /// The projections's Y column. Also accessible by using the index position <c>[1]</c>. + /// The projection's Y column. Also accessible by using the index position <c>[1]</c>. /// </summary> public Vector4 y; /// <summary> - /// The projections's Z column. Also accessible by using the index position <c>[2]</c>. + /// The projection's Z column. Also accessible by using the index position <c>[2]</c>. /// </summary> public Vector4 z; /// <summary> - /// The projections's W column. Also accessible by using the index position <c>[3]</c>. + /// The projection's W column. Also accessible by using the index position <c>[3]</c>. /// </summary> public Vector4 w; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs index 10739c02a7..b9ee0bc278 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs @@ -59,9 +59,9 @@ namespace Godot } /// <summary> - /// Constructs a <see cref="StringName"/> from the given <paramref name="path"/> string. + /// Constructs a <see cref="StringName"/> from the given <paramref name="name"/> string. /// </summary> - /// <param name="path">String to construct the <see cref="StringName"/> from.</param> + /// <param name="name">String to construct the <see cref="StringName"/> from.</param> public StringName(string name) { if (!string.IsNullOrEmpty(name)) diff --git a/modules/raycast/SCsub b/modules/raycast/SCsub index ef4c598194..074795759a 100644 --- a/modules/raycast/SCsub +++ b/modules/raycast/SCsub @@ -66,7 +66,7 @@ if env["builtin_embree"]: env_raycast.Append(CPPDEFINES=["EMBREE_TARGET_SSE2", "EMBREE_LOWEST_ISA", "TASKING_INTERNAL", "NDEBUG"]) if not env.msvc: - if env["arch"] in ["x86", "x86_64"]: + if env["arch"] == "x86_64": env_raycast.Append(CPPFLAGS=["-msse2", "-mxsave"]) if env["platform"] == "windows": @@ -83,7 +83,7 @@ if env["builtin_embree"]: env_thirdparty.disable_warnings() env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources) - if not env["arch"] in ["x86", "x86_64"] or env.msvc: + if env["arch"] == "arm64" or env.msvc: # Embree needs those, it will automatically use SSE2NEON in ARM env_thirdparty.Append(CPPDEFINES=["__SSE2__", "__SSE__"]) diff --git a/modules/raycast/config.py b/modules/raycast/config.py index 7e8b3e9840..438779343e 100644 --- a/modules/raycast/config.py +++ b/modules/raycast/config.py @@ -1,18 +1,6 @@ def can_build(env, platform): - # Depends on Embree library, which only supports x86_64 and aarch64. - if env["arch"].startswith("rv") or env["arch"].startswith("ppc"): - return False - - if platform == "android": - return env["android_arch"] in ["arm64v8", "x86_64"] - - if platform == "javascript": - return False # No SIMD support yet - - if env["bits"] == "32": - return False - - return True + # Depends on Embree library, which only supports x86_64 and arm64. + return env["arch"] in ["x86_64", "arm64"] def configure(env): diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp index 4c9302eb0c..5f839bd979 100644 --- a/modules/svg/image_loader_svg.cpp +++ b/modules/svg/image_loader_svg.cpp @@ -136,11 +136,11 @@ void ImageLoaderSVG::get_recognized_extensions(List<String> *p_extensions) const p_extensions->push_back("svg"); } -Error ImageLoaderSVG::load_image(Ref<Image> p_image, Ref<FileAccess> p_fileaccess, bool p_force_linear, float p_scale) { +Error ImageLoaderSVG::load_image(Ref<Image> p_image, Ref<FileAccess> p_fileaccess, uint32_t p_flags, float p_scale) { String svg = p_fileaccess->get_as_utf8_string(); create_image_from_string(p_image, svg, p_scale, false, HashMap<Color, Color>()); ERR_FAIL_COND_V(p_image->is_empty(), FAILED); - if (p_force_linear) { + if (p_flags & FLAG_FORCE_LINEAR) { p_image->srgb_to_linear(); } return OK; diff --git a/modules/svg/image_loader_svg.h b/modules/svg/image_loader_svg.h index f28df60c44..fc89b63edb 100644 --- a/modules/svg/image_loader_svg.h +++ b/modules/svg/image_loader_svg.h @@ -39,7 +39,7 @@ class ImageLoaderSVG : public ImageFormatLoader { public: void create_image_from_string(Ref<Image> p_image, String p_string, float p_scale, bool p_upsample, const HashMap<Color, Color> &p_color_map); - virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> p_fileaccess, bool p_force_linear, float p_scale) override; + virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> p_fileaccess, uint32_t p_flags, float p_scale) override; virtual void get_recognized_extensions(List<String> *p_extensions) const override; }; diff --git a/modules/tga/image_loader_tga.cpp b/modules/tga/image_loader_tga.cpp index 08ad1ef9f8..16d9bf7b93 100644 --- a/modules/tga/image_loader_tga.cpp +++ b/modules/tga/image_loader_tga.cpp @@ -230,7 +230,7 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff return OK; } -Error ImageLoaderTGA::load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_force_linear, float p_scale) { +Error ImageLoaderTGA::load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale) { Vector<uint8_t> src_image; uint64_t src_image_len = f->get_length(); ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT); diff --git a/modules/tga/image_loader_tga.h b/modules/tga/image_loader_tga.h index 9b7cbbac77..d95c5ff30b 100644 --- a/modules/tga/image_loader_tga.h +++ b/modules/tga/image_loader_tga.h @@ -73,7 +73,7 @@ class ImageLoaderTGA : public ImageFormatLoader { static Error convert_to_image(Ref<Image> p_image, const uint8_t *p_buffer, const tga_header_s &p_header, const uint8_t *p_palette, const bool p_is_monochrome, size_t p_input_size); public: - virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_force_linear, float p_scale); + virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale); virtual void get_recognized_extensions(List<String> *p_extensions) const; ImageLoaderTGA(); }; diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp index 864df765ee..6f61251f9b 100644 --- a/modules/tinyexr/image_loader_tinyexr.cpp +++ b/modules/tinyexr/image_loader_tinyexr.cpp @@ -37,7 +37,7 @@ #include "thirdparty/tinyexr/tinyexr.h" -Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_force_linear, float p_scale) { +Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale) { Vector<uint8_t> src_image; uint64_t src_image_len = f->get_length(); ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT); @@ -229,7 +229,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, Ref<FileAccess> f, bool color.a = *a_channel++; } - if (p_force_linear) { + if (p_flags & FLAG_FORCE_LINEAR) { color = color.srgb_to_linear(); } @@ -260,7 +260,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, Ref<FileAccess> f, bool color.a = *a_channel++; } - if (p_force_linear) { + if (p_flags & FLAG_FORCE_LINEAR) { color = color.srgb_to_linear(); } diff --git a/modules/tinyexr/image_loader_tinyexr.h b/modules/tinyexr/image_loader_tinyexr.h index 0d3de93956..8da2a0d4af 100644 --- a/modules/tinyexr/image_loader_tinyexr.h +++ b/modules/tinyexr/image_loader_tinyexr.h @@ -35,7 +35,7 @@ class ImageLoaderTinyEXR : public ImageFormatLoader { public: - virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_force_linear, float p_scale); + virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale); virtual void get_recognized_extensions(List<String> *p_extensions) const; ImageLoaderTinyEXR(); }; diff --git a/modules/webp/image_loader_webp.cpp b/modules/webp/image_loader_webp.cpp index 778d562278..705ab508ab 100644 --- a/modules/webp/image_loader_webp.cpp +++ b/modules/webp/image_loader_webp.cpp @@ -48,7 +48,7 @@ static Ref<Image> _webp_mem_loader_func(const uint8_t *p_png, int p_size) { return img; } -Error ImageLoaderWebP::load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_force_linear, float p_scale) { +Error ImageLoaderWebP::load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale) { Vector<uint8_t> src_image; uint64_t src_image_len = f->get_length(); ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT); diff --git a/modules/webp/image_loader_webp.h b/modules/webp/image_loader_webp.h index 9a5dc6cd7c..d868ae3f7f 100644 --- a/modules/webp/image_loader_webp.h +++ b/modules/webp/image_loader_webp.h @@ -35,7 +35,7 @@ class ImageLoaderWebP : public ImageFormatLoader { public: - virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_force_linear, float p_scale); + virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale); virtual void get_recognized_extensions(List<String> *p_extensions) const; ImageLoaderWebP(); }; diff --git a/platform/android/SCsub b/platform/android/SCsub index d370a4d18d..344ca036de 100644 --- a/platform/android/SCsub +++ b/platform/android/SCsub @@ -41,13 +41,13 @@ lib = env_android.add_shared_library("#bin/libgodot", [android_objects], SHLIBSU env.Depends(lib, thirdparty_obj) lib_arch_dir = "" -if env["android_arch"] == "armv7": +if env["arch"] == "arm32": lib_arch_dir = "armeabi-v7a" -elif env["android_arch"] == "arm64v8": +elif env["arch"] == "arm64": lib_arch_dir = "arm64-v8a" -elif env["android_arch"] == "x86": +elif env["arch"] == "x86_32": lib_arch_dir = "x86" -elif env["android_arch"] == "x86_64": +elif env["arch"] == "x86_64": lib_arch_dir = "x86_64" else: print("WARN: Architecture not suitable for embedding into APK; keeping .so at \\bin") diff --git a/platform/android/detect.py b/platform/android/detect.py index 2ff5bf59ea..ad63821162 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -22,7 +22,6 @@ def get_opts(): return [ ("ANDROID_SDK_ROOT", "Path to the Android SDK", get_env_android_sdk_root()), ("ndk_platform", 'Target platform (android-<api>, e.g. "android-24")', "android-24"), - EnumVariable("android_arch", "Target architecture", "arm64v8", ("armv7", "arm64v8", "x86", "x86_64")), ] @@ -46,6 +45,7 @@ def get_ndk_version(): def get_flags(): return [ + ("arch", "arm64"), # Default for convenience. ("tools", False), ] @@ -75,35 +75,37 @@ def install_ndk_if_needed(env): def configure(env): + # Validate arch. + supported_arches = ["x86_32", "x86_64", "arm32", "arm64"] + if env["arch"] not in supported_arches: + print( + 'Unsupported CPU architecture "%s" for Android. Supported architectures are: %s.' + % (env["arch"], ", ".join(supported_arches)) + ) + sys.exit() + install_ndk_if_needed(env) ndk_root = env["ANDROID_NDK_ROOT"] # Architecture - if env["android_arch"] not in ["armv7", "arm64v8", "x86", "x86_64"]: - env["android_arch"] = "arm64v8" - - print("Building for Android, platform " + env["ndk_platform"] + " (" + env["android_arch"] + ")") - - if get_min_sdk_version(env["ndk_platform"]) < 21: - if env["android_arch"] == "x86_64" or env["android_arch"] == "arm64v8": - print( - "WARNING: android_arch=" - + env["android_arch"] - + " is not supported by ndk_platform lower than android-21; setting ndk_platform=android-21" - ) - env["ndk_platform"] = "android-21" + if get_min_sdk_version(env["ndk_platform"]) < 21 and env["arch"] in ["x86_64", "arm64"]: + print( + 'WARNING: arch="%s" is not supported with "ndk_platform" lower than "android-21". Forcing platform 21.' + % env["arch"] + ) + env["ndk_platform"] = "android-21" - if env["android_arch"] == "armv7": + if env["arch"] == "arm32": target_triple = "armv7a-linux-androideabi" env.extra_suffix = ".armv7" + env.extra_suffix - elif env["android_arch"] == "arm64v8": + elif env["arch"] == "arm64": target_triple = "aarch64-linux-android" env.extra_suffix = ".armv8" + env.extra_suffix - elif env["android_arch"] == "x86": + elif env["arch"] == "x86_32": target_triple = "i686-linux-android" env.extra_suffix = ".x86" + env.extra_suffix - elif env["android_arch"] == "x86_64": + elif env["arch"] == "x86_64": target_triple = "x86_64-linux-android" env.extra_suffix = ".x86_64" + env.extra_suffix @@ -176,14 +178,14 @@ def configure(env): if get_min_sdk_version(env["ndk_platform"]) >= 24: env.Append(CPPDEFINES=[("_FILE_OFFSET_BITS", 64)]) - if env["android_arch"] == "x86": + if env["arch"] == "x86_32": # The NDK adds this if targeting API < 24, so we can drop it when Godot targets it at least env.Append(CCFLAGS=["-mstackrealign"]) - elif env["android_arch"] == "armv7": + elif env["arch"] == "arm32": env.Append(CCFLAGS="-march=armv7-a -mfloat-abi=softfp".split()) env.Append(CPPDEFINES=["__ARM_ARCH_7__", "__ARM_ARCH_7A__"]) env.Append(CPPDEFINES=["__ARM_NEON__"]) - elif env["android_arch"] == "arm64v8": + elif env["arch"] == "arm64": env.Append(CCFLAGS=["-mfix-cortex-a53-835769"]) env.Append(CPPDEFINES=["__ARM_ARCH_8A__"]) diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index 685b1f01af..016af40b52 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -588,9 +588,9 @@ zip_fileinfo EditorExportPlatformAndroid::get_zip_fileinfo() { Vector<String> EditorExportPlatformAndroid::get_abis() { Vector<String> abis; - abis.push_back("armeabi-v7a"); - abis.push_back("arm64-v8a"); - abis.push_back("x86"); + abis.push_back("arm32"); + abis.push_back("arm64"); + abis.push_back("x86_32"); abis.push_back("x86_64"); return abis; } @@ -1710,7 +1710,7 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio const String abi = abis[i]; // All Android devices supporting Vulkan run 64-bit Android, // so there is usually no point in exporting for 32-bit Android. - const bool is_default = abi == "arm64-v8a"; + const bool is_default = abi == "arm64"; r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, vformat("%s/%s", PNAME("architectures"), abi)), is_default)); } diff --git a/platform/android/java/build.gradle b/platform/android/java/build.gradle index da30bd3a95..81c7130c03 100644 --- a/platform/android/java/build.gradle +++ b/platform/android/java/build.gradle @@ -28,7 +28,7 @@ allprojects { } ext { - supportedAbis = ["armv7", "arm64v8", "x86", "x86_64"] + supportedAbis = ["arm32", "arm64", "x86_32", "x86_64"] supportedTargetsMap = [release: "release", dev: "debug", debug: "release_debug"] supportedFlavors = ["editor", "template"] @@ -37,7 +37,7 @@ ext { // If building manually on the command line, it's recommended to use the // `./gradlew generateGodotTemplates` build command instead after running the `scons` command(s). // The {selectedAbis} values must be from the {supportedAbis} values. - selectedAbis = ["arm64v8"] + selectedAbis = ["arm64"] } def rootDir = "../../.." diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle index 6b82326a27..318ae1143f 100644 --- a/platform/android/java/lib/build.gradle +++ b/platform/android/java/lib/build.gradle @@ -159,7 +159,7 @@ android { def taskName = getSconsTaskName(flavorName, buildType, selectedAbi) tasks.create(name: taskName, type: Exec) { executable sconsExecutableFile.absolutePath - args "--directory=${pathToRootDir}", "platform=android", "tools=${toolsFlag}", "target=${sconsTarget}", "android_arch=${selectedAbi}", "-j" + Runtime.runtime.availableProcessors() + args "--directory=${pathToRootDir}", "platform=android", "tools=${toolsFlag}", "target=${sconsTarget}", "arch=${selectedAbi}", "-j" + Runtime.runtime.availableProcessors() } // Schedule the tasks so the generated libs are present before the aar file is packaged. diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 0f551e7f4f..f94614c741 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -370,15 +370,15 @@ bool OS_Android::_check_internal_feature_support(const String &p_feature) { return true; } #if defined(__aarch64__) - if (p_feature == "arm64-v8a") { + if (p_feature == "arm64-v8a" || p_feature == "arm64") { return true; } #elif defined(__ARM_ARCH_7A__) - if (p_feature == "armeabi-v7a" || p_feature == "armeabi") { + if (p_feature == "armeabi-v7a" || p_feature == "armeabi" || p_feature == "arm32") { return true; } #elif defined(__arm__) - if (p_feature == "armeabi") { + if (p_feature == "armeabi" || p_feature == "arm") { return true; } #endif diff --git a/platform/ios/detect.py b/platform/ios/detect.py index 67c90b10a0..1a8d24d12d 100644 --- a/platform/ios/detect.py +++ b/platform/ios/detect.py @@ -36,12 +36,22 @@ def get_opts(): def get_flags(): return [ + ("arch", "arm64"), # Default for convenience. ("tools", False), ("use_volk", False), ] def configure(env): + # Validate arch. + supported_arches = ["x86_64", "arm64"] + if env["arch"] not in supported_arches: + print( + 'Unsupported CPU architecture "%s" for iOS. Supported architectures are: %s.' + % (env["arch"], ", ".join(supported_arches)) + ) + sys.exit() + ## Build type if env["target"].startswith("release"): @@ -64,11 +74,6 @@ def configure(env): env.Append(CCFLAGS=["-flto"]) env.Append(LINKFLAGS=["-flto"]) - ## Architecture - env["bits"] = "64" - if env["arch"] != "x86_64": - env["arch"] = "arm64" - ## Compiler configuration # Save this in environment for use by other modules diff --git a/platform/ios/export/export_plugin.cpp b/platform/ios/export/export_plugin.cpp index 425a977569..db55c7944f 100644 --- a/platform/ios/export/export_plugin.cpp +++ b/platform/ios/export/export_plugin.cpp @@ -140,27 +140,27 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/photolibrary_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need access to the photo library"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::DICTIONARY, "privacy/photolibrary_usage_description_localized", PROPERTY_HINT_LOCALIZABLE_STRING), Dictionary())); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/iphone_120x120", PROPERTY_HINT_FILE, "*.png"), "")); // Home screen on iPhone/iPod Touch with Retina display - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/iphone_180x180", PROPERTY_HINT_FILE, "*.png"), "")); // Home screen on iPhone with Retina HD display + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/iphone_120x120", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); // Home screen on iPhone/iPod Touch with Retina display + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/iphone_180x180", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); // Home screen on iPhone with Retina HD display - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/ipad_76x76", PROPERTY_HINT_FILE, "*.png"), "")); // Home screen on iPad - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/ipad_152x152", PROPERTY_HINT_FILE, "*.png"), "")); // Home screen on iPad with Retina display - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/ipad_167x167", PROPERTY_HINT_FILE, "*.png"), "")); // Home screen on iPad Pro + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/ipad_76x76", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); // Home screen on iPad + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/ipad_152x152", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); // Home screen on iPad with Retina display + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/ipad_167x167", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); // Home screen on iPad Pro - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/app_store_1024x1024", PROPERTY_HINT_FILE, "*.png"), "")); // App Store + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/app_store_1024x1024", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); // App Store - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/spotlight_40x40", PROPERTY_HINT_FILE, "*.png"), "")); // Spotlight - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/spotlight_80x80", PROPERTY_HINT_FILE, "*.png"), "")); // Spotlight on devices with Retina display + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/spotlight_40x40", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); // Spotlight + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "icons/spotlight_80x80", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); // Spotlight on devices with Retina display r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "storyboard/use_launch_screen_storyboard"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "storyboard/image_scale_mode", PROPERTY_HINT_ENUM, "Same as Logo,Center,Scale to Fit,Scale to Fill,Scale"), 0)); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "storyboard/custom_image@2x", PROPERTY_HINT_FILE, "*.png"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "storyboard/custom_image@3x", PROPERTY_HINT_FILE, "*.png"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "storyboard/custom_image@2x", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "storyboard/custom_image@3x", PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "storyboard/use_custom_bg_color"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::COLOR, "storyboard/custom_bg_color"), Color())); for (uint64_t i = 0; i < sizeof(loading_screen_infos) / sizeof(loading_screen_infos[0]); ++i) { - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, loading_screen_infos[i].preset_key, PROPERTY_HINT_FILE, "*.png"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, loading_screen_infos[i].preset_key, PROPERTY_HINT_FILE, "*.png,*.jpg,*.jpeg"), "")); } } @@ -531,26 +531,27 @@ struct IconInfo { const char *actual_size_side; const char *scale; const char *unscaled_size; + const bool force_opaque; }; static const IconInfo icon_infos[] = { // Home screen on iPhone - { "icons/iphone_120x120", "iphone", "Icon-120.png", "120", "2x", "60x60" }, - { "icons/iphone_120x120", "iphone", "Icon-120.png", "120", "3x", "40x40" }, - { "icons/iphone_180x180", "iphone", "Icon-180.png", "180", "3x", "60x60" }, + { "icons/iphone_120x120", "iphone", "Icon-120.png", "120", "2x", "60x60", false }, + { "icons/iphone_120x120", "iphone", "Icon-120.png", "120", "3x", "40x40", false }, + { "icons/iphone_180x180", "iphone", "Icon-180.png", "180", "3x", "60x60", false }, // Home screen on iPad - { "icons/ipad_76x76", "ipad", "Icon-76.png", "76", "1x", "76x76" }, - { "icons/ipad_152x152", "ipad", "Icon-152.png", "152", "2x", "76x76" }, - { "icons/ipad_167x167", "ipad", "Icon-167.png", "167", "2x", "83.5x83.5" }, + { "icons/ipad_76x76", "ipad", "Icon-76.png", "76", "1x", "76x76", false }, + { "icons/ipad_152x152", "ipad", "Icon-152.png", "152", "2x", "76x76", false }, + { "icons/ipad_167x167", "ipad", "Icon-167.png", "167", "2x", "83.5x83.5", false }, // App Store - { "icons/app_store_1024x1024", "ios-marketing", "Icon-1024.png", "1024", "1x", "1024x1024" }, + { "icons/app_store_1024x1024", "ios-marketing", "Icon-1024.png", "1024", "1x", "1024x1024", true }, // Spotlight - { "icons/spotlight_40x40", "ipad", "Icon-40.png", "40", "1x", "40x40" }, - { "icons/spotlight_80x80", "iphone", "Icon-80.png", "80", "2x", "40x40" }, - { "icons/spotlight_80x80", "ipad", "Icon-80.png", "80", "2x", "40x40" } + { "icons/spotlight_40x40", "ipad", "Icon-40.png", "40", "1x", "40x40", false }, + { "icons/spotlight_80x80", "iphone", "Icon-80.png", "80", "2x", "40x40", false }, + { "icons/spotlight_80x80", "ipad", "Icon-80.png", "80", "2x", "40x40", false } }; Error EditorExportPlatformIOS::_export_icons(const Ref<EditorExportPreset> &p_preset, const String &p_iconset_dir) { @@ -570,14 +571,17 @@ Error EditorExportPlatformIOS::_export_icons(const Ref<EditorExportPreset> &p_pr Ref<Image> img = memnew(Image); Error err = ImageLoader::load_image(icon_path, img); if (err != OK) { - ERR_PRINT("Invalid icon (" + String(info.preset_key) + "): '" + icon_path + "'."); + add_message(EXPORT_MESSAGE_ERROR, TTR("Export Icons"), vformat("Invalid icon (%s): '%s'.", info.preset_key, icon_path)); + return ERR_UNCONFIGURED; + } + if (info.force_opaque && img->detect_alpha() != Image::ALPHA_NONE) { + add_message(EXPORT_MESSAGE_ERROR, TTR("Export Icons"), vformat("Icon (%s) must be opaque.", info.preset_key)); return ERR_UNCONFIGURED; } img->resize(side_size, side_size); err = img->save_png(p_iconset_dir + info.export_name); if (err) { - String err_str = String("Failed to export icon(" + String(info.preset_key) + "): '" + icon_path + "'."); - ERR_PRINT(err_str.utf8().get_data()); + add_message(EXPORT_MESSAGE_ERROR, TTR("Export Icons"), vformat("Failed to export icon (%s): '%s'.", info.preset_key, icon_path)); return err; } } else { @@ -585,11 +589,15 @@ Error EditorExportPlatformIOS::_export_icons(const Ref<EditorExportPreset> &p_pr Ref<Image> img = memnew(Image); Error err = ImageLoader::load_image(icon_path, img); if (err != OK) { - ERR_PRINT("Invalid icon (" + String(info.preset_key) + "): '" + icon_path + "'."); + add_message(EXPORT_MESSAGE_ERROR, TTR("Export Icons"), vformat("Invalid icon (%s): '%s'.", info.preset_key, icon_path)); + return ERR_UNCONFIGURED; + } + if (info.force_opaque && img->detect_alpha() != Image::ALPHA_NONE) { + add_message(EXPORT_MESSAGE_ERROR, TTR("Export Icons"), vformat("Icon (%s) must be opaque.", info.preset_key)); return ERR_UNCONFIGURED; } if (img->get_width() != side_size || img->get_height() != side_size) { - WARN_PRINT("Icon (" + String(info.preset_key) + "): '" + icon_path + "' has incorrect size (" + String::num_int64(img->get_width()) + "x" + String::num_int64(img->get_height()) + ") and was automatically resized to " + String::num_int64(side_size) + "x" + String::num_int64(side_size) + "."); + add_message(EXPORT_MESSAGE_WARNING, TTR("Export Icons"), vformat("Icon (%s): '%s' has incorrect size %s and was automatically resized to %s.", info.preset_key, icon_path, img->get_size(), Vector2i(side_size, side_size))); img->resize(side_size, side_size); err = img->save_png(p_iconset_dir + info.export_name); } else { @@ -597,8 +605,7 @@ Error EditorExportPlatformIOS::_export_icons(const Ref<EditorExportPreset> &p_pr } if (err) { - String err_str = String("Failed to export icon(" + String(info.preset_key) + "): '" + icon_path + "'."); - ERR_PRINT(err_str.utf8().get_data()); + add_message(EXPORT_MESSAGE_ERROR, TTR("Export Icons"), vformat("Failed to export icon (%s): '%s'.", info.preset_key, icon_path)); return err; } } diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py index a769260f01..048c9c2eb4 100644 --- a/platform/javascript/detect.py +++ b/platform/javascript/detect.py @@ -46,6 +46,7 @@ def get_opts(): def get_flags(): return [ + ("arch", "wasm32"), ("tools", False), ("builtin_pcre2_with_jit", False), ("vulkan", False), @@ -53,6 +54,15 @@ def get_flags(): def configure(env): + # Validate arch. + supported_arches = ["wasm32"] + if env["arch"] not in supported_arches: + print( + 'Unsupported CPU architecture "%s" for iOS. Supported architectures are: %s.' + % (env["arch"], ", ".join(supported_arches)) + ) + sys.exit() + try: env["initial_memory"] = int(env["initial_memory"]) except Exception: diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py index 00e2b9e6eb..8563cc3cb2 100644 --- a/platform/linuxbsd/detect.py +++ b/platform/linuxbsd/detect.py @@ -2,6 +2,7 @@ import os import platform import sys from methods import get_compiler_version, using_gcc +from platform_methods import detect_arch def is_active(): @@ -52,10 +53,21 @@ def get_opts(): def get_flags(): - return [] + return [ + ("arch", detect_arch()), + ] def configure(env): + # Validate arch. + supported_arches = ["x86_32", "x86_64", "arm32", "arm64", "rv64", "ppc32", "ppc64"] + if env["arch"] not in supported_arches: + print( + 'Unsupported CPU architecture "%s" for Linux / *BSD. Supported architectures are: %s.' + % (env["arch"], ", ".join(supported_arches)) + ) + sys.exit() + ## Build type if env["target"] == "release": @@ -80,23 +92,7 @@ def configure(env): env.Prepend(CCFLAGS=["-g3"]) env.Append(LINKFLAGS=["-rdynamic"]) - ## Architecture - - is64 = sys.maxsize > 2**32 - if env["bits"] == "default": - env["bits"] = "64" if is64 else "32" - - machines = { - "riscv64": "rv64", - "ppc64le": "ppc64", - "ppc64": "ppc64", - "ppcle": "ppc", - "ppc": "ppc", - } - - if env["arch"] == "" and platform.machine() in machines: - env["arch"] = machines[platform.machine()] - + # CPU architecture flags. if env["arch"] == "rv64": # G = General-purpose extensions, C = Compression extension (very common). env.Append(CCFLAGS=["-march=rv64gc"]) @@ -262,8 +258,7 @@ def configure(env): env["builtin_libvorbis"] = False # Needed to link against system libtheora env.ParseConfig("pkg-config theora theoradec --cflags --libs") else: - list_of_x86 = ["x86_64", "x86", "i386", "i586"] - if any(platform.machine() in s for s in list_of_x86): + if env["arch"] in ["x86_64", "x86_32"]: env["x86_libtheora_opt_gcc"] = True if not env["builtin_libvorbis"]: @@ -405,11 +400,12 @@ def configure(env): env.Append(LINKFLAGS=["-T", "platform/linuxbsd/pck_embed.legacy.ld"]) ## Cross-compilation - - if is64 and env["bits"] == "32": + # TODO: Support cross-compilation on architectures other than x86. + host_is_64_bit = sys.maxsize > 2**32 + if host_is_64_bit and env["arch"] == "x86_32": env.Append(CCFLAGS=["-m32"]) env.Append(LINKFLAGS=["-m32", "-L/usr/lib/i386-linux-gnu"]) - elif not is64 and env["bits"] == "64": + elif not host_is_64_bit and env["arch"] == "x86_64": env.Append(CCFLAGS=["-m64"]) env.Append(LINKFLAGS=["-m64", "-L/usr/lib/i686-linux-gnu"]) diff --git a/platform/macos/detect.py b/platform/macos/detect.py index 20e7afa772..e5bcb46b02 100644 --- a/platform/macos/detect.py +++ b/platform/macos/detect.py @@ -1,6 +1,7 @@ import os import sys from methods import detect_darwin_sdk_path +from platform_methods import detect_arch def is_active(): @@ -37,6 +38,7 @@ def get_opts(): def get_flags(): return [ + ("arch", detect_arch()), ("use_volk", False), ] @@ -71,6 +73,15 @@ def get_mvk_sdk_path(): def configure(env): + # Validate arch. + supported_arches = ["x86_64", "arm64"] + if env["arch"] not in supported_arches: + print( + 'Unsupported CPU architecture "%s" for macOS. Supported architectures are: %s.' + % (env["arch"], ", ".join(supported_arches)) + ) + sys.exit() + ## Build type if env["target"] == "release": @@ -96,25 +107,20 @@ def configure(env): env.Prepend(CCFLAGS=["-g3"]) env.Prepend(LINKFLAGS=["-Xlinker", "-no_deduplicate"]) - ## Architecture - - # macOS no longer runs on 32-bit since 10.7 which is unsupported since 2014 - # As such, we only support 64-bit - env["bits"] = "64" - ## Compiler configuration # Save this in environment for use by other modules if "OSXCROSS_ROOT" in os.environ: env["osxcross"] = True + # CPU architecture. if env["arch"] == "arm64": - print("Building for macOS 11.0+, platform arm64.") + print("Building for macOS 11.0+.") env.Append(ASFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.0"]) env.Append(CCFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.0"]) env.Append(LINKFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.0"]) - else: - print("Building for macOS 10.12+, platform x86_64.") + elif env["arch"] == "x86_64": + print("Building for macOS 10.12+.") env.Append(ASFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"]) env.Append(CCFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"]) env.Append(LINKFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"]) @@ -185,9 +191,8 @@ def configure(env): ## Dependencies - if env["builtin_libtheora"]: - if env["arch"] != "arm64": - env["x86_libtheora_opt_gcc"] = True + if env["builtin_libtheora"] and env["arch"] == "x86_64": + env["x86_libtheora_opt_gcc"] = True ## Flags diff --git a/platform/uwp/detect.py b/platform/uwp/detect.py index 9c91378b22..2c5746cb06 100644 --- a/platform/uwp/detect.py +++ b/platform/uwp/detect.py @@ -1,6 +1,7 @@ import methods import os import sys +from platform_methods import detect_arch def is_active(): @@ -31,6 +32,7 @@ def get_opts(): def get_flags(): return [ + ("arch", detect_arch()), ("tools", False), ("xaudio2", True), ("builtin_pcre2_with_jit", False), @@ -38,19 +40,17 @@ def get_flags(): def configure(env): - env.msvc = True - - if env["bits"] != "default": - print("Error: bits argument is disabled for MSVC") + # Validate arch. + supported_arches = ["x86_32", "x86_64", "arm32"] + if env["arch"] not in supported_arches: print( - """ - Bits argument is not supported for MSVC compilation. Architecture depends on the Native/Cross Compile Tools Prompt/Developer Console - (or Visual Studio settings) that is being used to run SCons. As a consequence, bits argument is disabled. Run scons again without bits - argument (example: scons p=uwp) and SCons will attempt to detect what MSVC compiler will be executed and inform you. - """ + 'Unsupported CPU architecture "%s" for UWP. Supported architectures are: %s.' + % (env["arch"], ", ".join(supported_arches)) ) sys.exit() + env.msvc = True + ## Build type if env["target"] == "release": @@ -101,11 +101,10 @@ def configure(env): arch = "" if str(os.getenv("Platform")).lower() == "arm": - - print("Compiled program architecture will be an ARM executable. (forcing bits=32).") + print("Compiled program architecture will be an ARM executable (forcing arch=arm32).") arch = "arm" - env["bits"] = "32" + env["arch"] = "arm32" env.Append(LINKFLAGS=["/MACHINE:ARM"]) env.Append(LIBPATH=[vc_base_path + "lib/store/arm"]) @@ -117,20 +116,20 @@ def configure(env): compiler_version_str = methods.detect_visual_c_compiler_version(env["ENV"]) if compiler_version_str == "amd64" or compiler_version_str == "x86_amd64": - env["bits"] = "64" - print("Compiled program architecture will be a x64 executable (forcing bits=64).") + env["arch"] = "x86_64" + print("Compiled program architecture will be a x64 executable (forcing arch=x86_64).") elif compiler_version_str == "x86" or compiler_version_str == "amd64_x86": - env["bits"] = "32" - print("Compiled program architecture will be a x86 executable. (forcing bits=32).") + env["arch"] = "x86_32" + print("Compiled program architecture will be a x86 executable (forcing arch=x86_32).") else: print( - "Failed to detect MSVC compiler architecture version... Defaulting to 32-bit executable settings" - " (forcing bits=32). Compilation attempt will continue, but SCons can not detect for what architecture" + "Failed to detect MSVC compiler architecture version... Defaulting to x86 32-bit executable settings" + " (forcing arch=x86_32). Compilation attempt will continue, but SCons can not detect for what architecture" " this build is compiled for. You should check your settings/compilation setup." ) - env["bits"] = "32" + env["arch"] = "x86_32" - if env["bits"] == "32": + if env["arch"] == "x86_32": arch = "x86" angle_build_cmd += "Win32" diff --git a/platform/windows/detect.py b/platform/windows/detect.py index dd2df1f004..6dd6892757 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -1,5 +1,6 @@ import methods import os +from platform_methods import detect_arch # To match other platforms STACK_SIZE = 8388608 @@ -46,6 +47,7 @@ def can_build(): def get_opts(): from SCons.Variables import BoolVariable, EnumVariable + # TODO: These shouldn't be hard-coded for x86. mingw32 = "" mingw64 = "" if os.name == "posix": @@ -77,11 +79,14 @@ def get_opts(): def get_flags(): - return [] + return [ + ("arch", detect_arch()), + ] def build_res_file(target, source, env): - if env["bits"] == "32": + # TODO: This shouldn't be hard-coded for x86. + if env["arch"] == "x86_32": cmdbase = env["mingw_prefix_32"] else: cmdbase = env["mingw_prefix_64"] @@ -100,21 +105,27 @@ def build_res_file(target, source, env): def setup_msvc_manual(env): + # FIXME: This is super hacky, and probably obsolete. + # Won't work with detect_arch() used for `arch` by default. + """Set up env to use MSVC manually, using VCINSTALLDIR""" - if env["bits"] != "default": + if env["arch"] != "auto": print( """ - Bits argument is not supported for MSVC compilation. Architecture depends on the Native/Cross Compile Tools Prompt/Developer Console - (or Visual Studio settings) that is being used to run SCons. As a consequence, bits argument is disabled. Run scons again without bits - argument (example: scons p=windows) and SCons will attempt to detect what MSVC compiler will be executed and inform you. + Arch argument is not supported for MSVC manual configuration (VCINSTALLDIR configured). + Architecture depends on the Native/Cross Compile Tools Prompt/Developer Console (or Visual Studio settings) that is being used to run SCons. + As a consequence, the arch argument is disabled. Run scons again without arch argument (example: scons p=windows) + and SCons will attempt to detect what MSVC compiler will be executed and inform you. """ ) - raise SCons.Errors.UserError("Bits argument should not be used when using VCINSTALLDIR") + raise SCons.Errors.UserError("Arch argument should not be used when using VCINSTALLDIR") - # Force bits arg + # Force ARCH arg # (Actually msys2 mingw can support 64-bit, we could detect that) - env["bits"] = "32" - env["x86_libtheora_opt_vc"] = True + # TODO: This is wrong, but not sure what to do about it. + # We want to determine the arch and bitness in the SConstruct only. + # We can check if it's correct in here, but if it's not, it should + # just fail with an error message instead of trying to force it. # find compiler manually compiler_version_str = methods.detect_visual_c_compiler_version(env["ENV"]) @@ -122,17 +133,19 @@ def setup_msvc_manual(env): # If building for 64bit architecture, disable assembly optimisations for 32 bit builds (theora as of writing)... vc compiler for 64bit can not compile _asm if compiler_version_str == "amd64" or compiler_version_str == "x86_amd64": - env["bits"] = "64" + env["arch"] = "x86_64" env["x86_libtheora_opt_vc"] = False - print("Compiled program architecture will be a 64 bit executable (forcing bits=64).") + print("Compiled program architecture will be a 64 bit executable (forcing arch=x86_64).") elif compiler_version_str == "x86" or compiler_version_str == "amd64_x86": - print("Compiled program architecture will be a 32 bit executable. (forcing bits=32).") + env["arch"] = "x86_32" + env["x86_libtheora_opt_vc"] = True + print("Compiled program architecture will be a 32 bit executable (forcing arch=x86_32).") else: print( - "Failed to manually detect MSVC compiler architecture version... Defaulting to 32bit executable settings" - " (forcing bits=32). Compilation attempt will continue, but SCons can not detect for what architecture this" - " build is compiled for. You should check your settings/compilation setup, or avoid setting VCINSTALLDIR." + "Failed to manually detect MSVC compiler architecture version.\n" + "You should check your settings/compilation setup, or avoid setting VCINSTALLDIR." ) + sys.exit() def setup_msvc_auto(env): @@ -141,6 +154,18 @@ def setup_msvc_auto(env): # If MSVC_VERSION is set by SCons, we know MSVC is installed. # But we may want a different version or target arch. + # Valid architectures for MSVC's TARGET_ARCH: + # ['amd64', 'emt64', 'i386', 'i486', 'i586', 'i686', 'ia64', 'itanium', 'x86', 'x86_64', 'arm', 'arm64', 'aarch64'] + # Our x86_64 and arm64 are the same, and we need to map the 32-bit + # architectures to other names since MSVC isn't as explicit. + # The rest we don't need to worry about because they are + # aliases or aren't supported by Godot (itanium & ia64). + msvc_arch_aliases = {"x86_32": "x86", "arm32": "arm"} + if env["arch"] in msvc_arch_aliases.keys(): + env["TARGET_ARCH"] = msvc_arch_aliases[env["arch"]] + else: + env["TARGET_ARCH"] = env["arch"] + # The env may have already been set up with default MSVC tools, so # reset a few things so we can set it up with the tools we want. # (Ideally we'd decide on the tool config before configuring any @@ -149,21 +174,14 @@ def setup_msvc_auto(env): env["MSVC_SETUP_RUN"] = False # Need to set this to re-run the tool env["MSVS_VERSION"] = None env["MSVC_VERSION"] = None - env["TARGET_ARCH"] = None - if env["bits"] != "default": - env["TARGET_ARCH"] = {"32": "x86", "64": "x86_64"}[env["bits"]] + if "msvc_version" in env: env["MSVC_VERSION"] = env["msvc_version"] env.Tool("msvc") env.Tool("mssdk") # we want the MS SDK # Note: actual compiler version can be found in env['MSVC_VERSION'], e.g. "14.1" for VS2015 - # Get actual target arch into bits (it may be "default" at this point): - if env["TARGET_ARCH"] in ("amd64", "x86_64"): - env["bits"] = "64" - else: - env["bits"] = "32" - print("Found MSVC version %s, arch %s, bits=%s" % (env["MSVC_VERSION"], env["TARGET_ARCH"], env["bits"])) - if env["TARGET_ARCH"] in ("amd64", "x86_64"): + print("Found MSVC version %s, arch %s" % (env["MSVC_VERSION"], env["TARGET_ARCH"])) + if env["arch"] == "x86_32": env["x86_libtheora_opt_vc"] = False @@ -244,7 +262,7 @@ def configure_msvc(env, manual_msvc_config): ] ) env.AppendUnique(CPPDEFINES=["NOMINMAX"]) # disable bogus min/max WinDef.h macros - if env["bits"] == "64": + if env["arch"] == "x86_64": env.AppendUnique(CPPDEFINES=["_WIN64"]) ## Libs @@ -328,10 +346,10 @@ def configure_mingw(env): env.Append(CCFLAGS=["-msse2"]) if env["optimize"] == "speed": # optimize for speed (default) - if env["bits"] == "64": - env.Append(CCFLAGS=["-O3"]) - else: + if env["arch"] == "x86_32": env.Append(CCFLAGS=["-O2"]) + else: + env.Append(CCFLAGS=["-O3"]) else: # optimize for size env.Prepend(CCFLAGS=["-Os"]) @@ -365,15 +383,12 @@ def configure_mingw(env): if os.name != "nt": env["PROGSUFFIX"] = env["PROGSUFFIX"] + ".exe" # for linux cross-compilation - if env["bits"] == "default": - if os.name == "nt": - env["bits"] = "64" if "PROGRAMFILES(X86)" in os.environ else "32" - else: # default to 64-bit on Linux - env["bits"] = "64" - mingw_prefix = "" - if env["bits"] == "32": + # TODO: This doesn't seem to be working, or maybe I just have + # MinGW set up incorrectly. It always gives me x86_64 builds, + # even though arch == "x86_32" and the file name has x86_32 in it. + if env["arch"] == "x86_32": if env["use_static_cpp"]: env.Append(LINKFLAGS=["-static"]) env.Append(LINKFLAGS=["-static-libgcc"]) @@ -460,11 +475,18 @@ def configure_mingw(env): def configure(env): + # Validate arch. + supported_arches = ["x86_32", "x86_64", "arm32", "arm64"] + if env["arch"] not in supported_arches: + print( + 'Unsupported CPU architecture "%s" for Windows. Supported architectures are: %s.' + % (env["arch"], ", ".join(supported_arches)) + ) + sys.exit() + # At this point the env has been set up with basic tools/compilers. env.Prepend(CPPPATH=["#platform/windows"]) - print("Configuring for Windows: target=%s, bits=%s" % (env["target"], env["bits"])) - if os.name == "nt": env["ENV"] = os.environ # this makes build less repeatable, but simplifies some things env["ENV"]["TMP"] = os.environ["TMP"] diff --git a/platform/windows/platform_windows_builders.py b/platform/windows/platform_windows_builders.py index 22e33b51b4..33ca2e8ffa 100644 --- a/platform/windows/platform_windows_builders.py +++ b/platform/windows/platform_windows_builders.py @@ -9,7 +9,7 @@ from platform_methods import subprocess_main def make_debug_mingw(target, source, env): mingw_prefix = "" - if env["bits"] == "32": + if env["arch"] == "x86_32": mingw_prefix = env["mingw_prefix_32"] else: mingw_prefix = env["mingw_prefix_64"] diff --git a/platform_methods.py b/platform_methods.py index be4957475d..1a2520794c 100644 --- a/platform_methods.py +++ b/platform_methods.py @@ -1,6 +1,7 @@ import os import sys import json +import platform import uuid import functools import subprocess @@ -71,9 +72,42 @@ def run_in_subprocess(builder_function): def subprocess_main(namespace): - with open(sys.argv[1]) as json_file: data = json.load(json_file) fn = namespace[data["fn"]] fn(*data["args"]) + + +# CPU architecture options. +architectures = ["x86_32", "x86_64", "arm32", "arm64", "rv64", "ppc32", "ppc64", "wasm32"] +architecture_aliases = { + "x86": "x86_32", + "x64": "x86_64", + "amd64": "x86_64", + "armv7": "arm32", + "armv8": "arm64", + "arm64v8": "arm64", + "aarch64": "arm64", + "rv": "rv64", + "riscv": "rv64", + "riscv64": "rv64", + "ppcle": "ppc32", + "ppc": "ppc32", + "ppc64le": "ppc64", +} + + +def detect_arch(): + host_machine = platform.machine().lower() + if host_machine in architectures: + return host_machine + elif host_machine in architecture_aliases.keys(): + return architecture_aliases[host_machine] + elif "86" in host_machine: + # Catches x86, i386, i486, i586, i686, etc. + return "x86_32" + else: + print("Unsupported CPU architecture: " + host_machine) + print("Falling back to x86_64.") + return "x86_64" diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 163340e306..a317285a1b 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -1114,9 +1114,9 @@ bool CharacterBody2D::move_and_slide() { if ((on_floor || on_wall) && platform_rid.is_valid()) { bool excluded = false; if (on_floor) { - excluded = (moving_platform_floor_layers & platform_layer) == 0; + excluded = (platform_floor_layers & platform_layer) == 0; } else if (on_wall) { - excluded = (moving_platform_wall_layers & platform_layer) == 0; + excluded = (platform_wall_layers & platform_layer) == 0; } if (!excluded) { //this approach makes sure there is less delay between the actual body velocity and the one we saved @@ -1166,10 +1166,10 @@ bool CharacterBody2D::move_and_slide() { // Compute real velocity. real_velocity = get_position_delta() / delta; - if (moving_platform_apply_velocity_on_leave != PLATFORM_VEL_ON_LEAVE_NEVER) { + if (platform_on_leave != PLATFORM_ON_LEAVE_DO_NOTHING) { // Add last platform velocity when just left a moving platform. if (!on_floor && !on_wall) { - if (moving_platform_apply_velocity_on_leave == PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY && current_platform_velocity.dot(up_direction) < 0) { + if (platform_on_leave == PLATFORM_ON_LEAVE_ADD_UPWARD_VELOCITY && current_platform_velocity.dot(up_direction) < 0) { current_platform_velocity = current_platform_velocity.slide(up_direction); } velocity += current_platform_velocity; @@ -1613,20 +1613,20 @@ void CharacterBody2D::set_slide_on_ceiling_enabled(bool p_enabled) { slide_on_ceiling = p_enabled; } -uint32_t CharacterBody2D::get_moving_platform_floor_layers() const { - return moving_platform_floor_layers; +uint32_t CharacterBody2D::get_platform_floor_layers() const { + return platform_floor_layers; } -void CharacterBody2D::set_moving_platform_floor_layers(uint32_t p_exclude_layers) { - moving_platform_floor_layers = p_exclude_layers; +void CharacterBody2D::set_platform_floor_layers(uint32_t p_exclude_layers) { + platform_floor_layers = p_exclude_layers; } -uint32_t CharacterBody2D::get_moving_platform_wall_layers() const { - return moving_platform_wall_layers; +uint32_t CharacterBody2D::get_platform_wall_layers() const { + return platform_wall_layers; } -void CharacterBody2D::set_moving_platform_wall_layers(uint32_t p_exclude_layers) { - moving_platform_wall_layers = p_exclude_layers; +void CharacterBody2D::set_platform_wall_layers(uint32_t p_exclude_layers) { + platform_wall_layers = p_exclude_layers; } void CharacterBody2D::set_motion_mode(MotionMode p_mode) { @@ -1637,12 +1637,12 @@ CharacterBody2D::MotionMode CharacterBody2D::get_motion_mode() const { return motion_mode; } -void CharacterBody2D::set_moving_platform_apply_velocity_on_leave(MovingPlatformApplyVelocityOnLeave p_on_leave_apply_velocity) { - moving_platform_apply_velocity_on_leave = p_on_leave_apply_velocity; +void CharacterBody2D::set_platform_on_leave(PlatformOnLeave p_on_leave_apply_velocity) { + platform_on_leave = p_on_leave_apply_velocity; } -CharacterBody2D::MovingPlatformApplyVelocityOnLeave CharacterBody2D::get_moving_platform_apply_velocity_on_leave() const { - return moving_platform_apply_velocity_on_leave; +CharacterBody2D::PlatformOnLeave CharacterBody2D::get_platform_on_leave() const { + return platform_on_leave; } int CharacterBody2D::get_max_slides() const { @@ -1720,10 +1720,10 @@ void CharacterBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_slide_on_ceiling_enabled", "enabled"), &CharacterBody2D::set_slide_on_ceiling_enabled); ClassDB::bind_method(D_METHOD("is_slide_on_ceiling_enabled"), &CharacterBody2D::is_slide_on_ceiling_enabled); - ClassDB::bind_method(D_METHOD("set_moving_platform_floor_layers", "exclude_layer"), &CharacterBody2D::set_moving_platform_floor_layers); - ClassDB::bind_method(D_METHOD("get_moving_platform_floor_layers"), &CharacterBody2D::get_moving_platform_floor_layers); - ClassDB::bind_method(D_METHOD("set_moving_platform_wall_layers", "exclude_layer"), &CharacterBody2D::set_moving_platform_wall_layers); - ClassDB::bind_method(D_METHOD("get_moving_platform_wall_layers"), &CharacterBody2D::get_moving_platform_wall_layers); + ClassDB::bind_method(D_METHOD("set_platform_floor_layers", "exclude_layer"), &CharacterBody2D::set_platform_floor_layers); + ClassDB::bind_method(D_METHOD("get_platform_floor_layers"), &CharacterBody2D::get_platform_floor_layers); + ClassDB::bind_method(D_METHOD("set_platform_wall_layers", "exclude_layer"), &CharacterBody2D::set_platform_wall_layers); + ClassDB::bind_method(D_METHOD("get_platform_wall_layers"), &CharacterBody2D::get_platform_wall_layers); ClassDB::bind_method(D_METHOD("get_max_slides"), &CharacterBody2D::get_max_slides); ClassDB::bind_method(D_METHOD("set_max_slides", "max_slides"), &CharacterBody2D::set_max_slides); @@ -1737,8 +1737,8 @@ void CharacterBody2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_up_direction", "up_direction"), &CharacterBody2D::set_up_direction); ClassDB::bind_method(D_METHOD("set_motion_mode", "mode"), &CharacterBody2D::set_motion_mode); ClassDB::bind_method(D_METHOD("get_motion_mode"), &CharacterBody2D::get_motion_mode); - ClassDB::bind_method(D_METHOD("set_moving_platform_apply_velocity_on_leave", "on_leave_apply_velocity"), &CharacterBody2D::set_moving_platform_apply_velocity_on_leave); - ClassDB::bind_method(D_METHOD("get_moving_platform_apply_velocity_on_leave"), &CharacterBody2D::get_moving_platform_apply_velocity_on_leave); + ClassDB::bind_method(D_METHOD("set_platform_on_leave", "on_leave_apply_velocity"), &CharacterBody2D::set_platform_on_leave); + ClassDB::bind_method(D_METHOD("get_platform_on_leave"), &CharacterBody2D::get_platform_on_leave); ClassDB::bind_method(D_METHOD("is_on_floor"), &CharacterBody2D::is_on_floor); ClassDB::bind_method(D_METHOD("is_on_floor_only"), &CharacterBody2D::is_on_floor_only); @@ -1771,10 +1771,10 @@ void CharacterBody2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_max_angle", PROPERTY_HINT_RANGE, "0,180,0.1,radians"), "set_floor_max_angle", "get_floor_max_angle"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_snap_length", PROPERTY_HINT_RANGE, "0,32,0.1,or_greater,suffix:px"), "set_floor_snap_length", "get_floor_snap_length"); - ADD_GROUP("Moving Platform", "moving_platform"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "moving_platform_apply_velocity_on_leave", PROPERTY_HINT_ENUM, "Always,Upward Only,Never", PROPERTY_USAGE_DEFAULT), "set_moving_platform_apply_velocity_on_leave", "get_moving_platform_apply_velocity_on_leave"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "moving_platform_floor_layers", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_moving_platform_floor_layers", "get_moving_platform_floor_layers"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "moving_platform_wall_layers", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_moving_platform_wall_layers", "get_moving_platform_wall_layers"); + ADD_GROUP("Moving Platform", "platform"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "platform_on_leave", PROPERTY_HINT_ENUM, "Add Velocity,Add Upward Velocity,Do Nothing", PROPERTY_USAGE_DEFAULT), "set_platform_on_leave", "get_platform_on_leave"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "platform_floor_layers", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_platform_floor_layers", "get_platform_floor_layers"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "platform_wall_layers", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_platform_wall_layers", "get_platform_wall_layers"); ADD_GROUP("Collision", ""); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001,suffix:px"), "set_safe_margin", "get_safe_margin"); @@ -1782,9 +1782,9 @@ void CharacterBody2D::_bind_methods() { BIND_ENUM_CONSTANT(MOTION_MODE_GROUNDED); BIND_ENUM_CONSTANT(MOTION_MODE_FLOATING); - BIND_ENUM_CONSTANT(PLATFORM_VEL_ON_LEAVE_ALWAYS); - BIND_ENUM_CONSTANT(PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY); - BIND_ENUM_CONSTANT(PLATFORM_VEL_ON_LEAVE_NEVER); + BIND_ENUM_CONSTANT(PLATFORM_ON_LEAVE_ADD_VELOCITY); + BIND_ENUM_CONSTANT(PLATFORM_ON_LEAVE_ADD_UPWARD_VELOCITY); + BIND_ENUM_CONSTANT(PLATFORM_ON_LEAVE_DO_NOTHING); } void CharacterBody2D::_validate_property(PropertyInfo &p_property) const { diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index 2f9a27b41e..fe64c087c6 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -331,10 +331,10 @@ public: MOTION_MODE_GROUNDED, MOTION_MODE_FLOATING, }; - enum MovingPlatformApplyVelocityOnLeave { - PLATFORM_VEL_ON_LEAVE_ALWAYS, - PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY, - PLATFORM_VEL_ON_LEAVE_NEVER, + enum PlatformOnLeave { + PLATFORM_ON_LEAVE_ADD_VELOCITY, + PLATFORM_ON_LEAVE_ADD_UPWARD_VELOCITY, + PLATFORM_ON_LEAVE_DO_NOTHING, }; bool move_and_slide(); @@ -365,7 +365,7 @@ public: private: real_t margin = 0.08; MotionMode motion_mode = MOTION_MODE_GROUNDED; - MovingPlatformApplyVelocityOnLeave moving_platform_apply_velocity_on_leave = PLATFORM_VEL_ON_LEAVE_ALWAYS; + PlatformOnLeave platform_on_leave = PLATFORM_ON_LEAVE_ADD_VELOCITY; bool floor_constant_speed = false; bool floor_stop_on_slope = true; @@ -377,8 +377,8 @@ private: real_t floor_snap_length = 1; real_t wall_min_slide_angle = Math::deg2rad((real_t)15.0); Vector2 up_direction = Vector2(0.0, -1.0); - uint32_t moving_platform_floor_layers = UINT32_MAX; - uint32_t moving_platform_wall_layers = 0; + uint32_t platform_floor_layers = UINT32_MAX; + uint32_t platform_wall_layers = 0; Vector2 velocity; Vector2 floor_normal; @@ -424,17 +424,17 @@ private: real_t get_wall_min_slide_angle() const; void set_wall_min_slide_angle(real_t p_radians); - uint32_t get_moving_platform_floor_layers() const; - void set_moving_platform_floor_layers(const uint32_t p_exclude_layer); + uint32_t get_platform_floor_layers() const; + void set_platform_floor_layers(const uint32_t p_exclude_layer); - uint32_t get_moving_platform_wall_layers() const; - void set_moving_platform_wall_layers(const uint32_t p_exclude_layer); + uint32_t get_platform_wall_layers() const; + void set_platform_wall_layers(const uint32_t p_exclude_layer); void set_motion_mode(MotionMode p_mode); MotionMode get_motion_mode() const; - void set_moving_platform_apply_velocity_on_leave(MovingPlatformApplyVelocityOnLeave p_on_leave_velocity); - MovingPlatformApplyVelocityOnLeave get_moving_platform_apply_velocity_on_leave() const; + void set_platform_on_leave(PlatformOnLeave p_on_leave_velocity); + PlatformOnLeave get_platform_on_leave() const; void _move_and_slide_floating(double p_delta); void _move_and_slide_grounded(double p_delta, bool p_was_on_floor); @@ -455,7 +455,7 @@ protected: }; VARIANT_ENUM_CAST(CharacterBody2D::MotionMode); -VARIANT_ENUM_CAST(CharacterBody2D::MovingPlatformApplyVelocityOnLeave); +VARIANT_ENUM_CAST(CharacterBody2D::PlatformOnLeave); class KinematicCollision2D : public RefCounted { GDCLASS(KinematicCollision2D, RefCounted); diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index 6b4ec7121f..c690b5d6ff 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -525,7 +525,7 @@ void RigidDynamicBody3D::_body_state_changed(PhysicsDirectBodyState3D *p_state) } _RigidDynamicBodyInOut *toadd = (_RigidDynamicBodyInOut *)alloca(p_state->get_contact_count() * sizeof(_RigidDynamicBodyInOut)); - int toadd_count = 0; //state->get_contact_count(); + int toadd_count = 0; RigidDynamicBody3D_RemoveAction *toremove = (RigidDynamicBody3D_RemoveAction *)alloca(rc * sizeof(RigidDynamicBody3D_RemoveAction)); int toremove_count = 0; @@ -537,8 +537,6 @@ void RigidDynamicBody3D::_body_state_changed(PhysicsDirectBodyState3D *p_state) int local_shape = p_state->get_contact_local_shape(i); int shape = p_state->get_contact_collider_shape(i); - //bool found=false; - HashMap<ObjectID, BodyState>::Iterator E = contact_monitor->body_map.find(obj); if (!E) { toadd[toadd_count].rid = rid; @@ -1183,9 +1181,9 @@ bool CharacterBody3D::move_and_slide() { if ((collision_state.floor || collision_state.wall) && platform_rid.is_valid()) { bool excluded = false; if (collision_state.floor) { - excluded = (moving_platform_floor_layers & platform_layer) == 0; + excluded = (platform_floor_layers & platform_layer) == 0; } else if (collision_state.wall) { - excluded = (moving_platform_wall_layers & platform_layer) == 0; + excluded = (platform_wall_layers & platform_layer) == 0; } if (!excluded) { //this approach makes sure there is less delay between the actual body velocity and the one we saved @@ -1237,10 +1235,10 @@ bool CharacterBody3D::move_and_slide() { // Compute real velocity. real_velocity = get_position_delta() / delta; - if (moving_platform_apply_velocity_on_leave != PLATFORM_VEL_ON_LEAVE_NEVER) { + if (platform_on_leave != PLATFORM_ON_LEAVE_DO_NOTHING) { // Add last platform velocity when just left a moving platform. if (!collision_state.floor && !collision_state.wall) { - if (moving_platform_apply_velocity_on_leave == PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY && current_platform_velocity.dot(up_direction) < 0) { + if (platform_on_leave == PLATFORM_ON_LEAVE_ADD_UPWARD_VELOCITY && current_platform_velocity.dot(up_direction) < 0) { current_platform_velocity = current_platform_velocity.slide(up_direction); } velocity += current_platform_velocity; @@ -1860,20 +1858,20 @@ void CharacterBody3D::set_slide_on_ceiling_enabled(bool p_enabled) { slide_on_ceiling = p_enabled; } -uint32_t CharacterBody3D::get_moving_platform_floor_layers() const { - return moving_platform_floor_layers; +uint32_t CharacterBody3D::get_platform_floor_layers() const { + return platform_floor_layers; } -void CharacterBody3D::set_moving_platform_floor_layers(uint32_t p_exclude_layers) { - moving_platform_floor_layers = p_exclude_layers; +void CharacterBody3D::set_platform_floor_layers(uint32_t p_exclude_layers) { + platform_floor_layers = p_exclude_layers; } -uint32_t CharacterBody3D::get_moving_platform_wall_layers() const { - return moving_platform_wall_layers; +uint32_t CharacterBody3D::get_platform_wall_layers() const { + return platform_wall_layers; } -void CharacterBody3D::set_moving_platform_wall_layers(uint32_t p_exclude_layers) { - moving_platform_wall_layers = p_exclude_layers; +void CharacterBody3D::set_platform_wall_layers(uint32_t p_exclude_layers) { + platform_wall_layers = p_exclude_layers; } void CharacterBody3D::set_motion_mode(MotionMode p_mode) { @@ -1884,12 +1882,12 @@ CharacterBody3D::MotionMode CharacterBody3D::get_motion_mode() const { return motion_mode; } -void CharacterBody3D::set_moving_platform_apply_velocity_on_leave(MovingPlatformApplyVelocityOnLeave p_on_leave_apply_velocity) { - moving_platform_apply_velocity_on_leave = p_on_leave_apply_velocity; +void CharacterBody3D::set_platform_on_leave(PlatformOnLeave p_on_leave_apply_velocity) { + platform_on_leave = p_on_leave_apply_velocity; } -CharacterBody3D::MovingPlatformApplyVelocityOnLeave CharacterBody3D::get_moving_platform_apply_velocity_on_leave() const { - return moving_platform_apply_velocity_on_leave; +CharacterBody3D::PlatformOnLeave CharacterBody3D::get_platform_on_leave() const { + return platform_on_leave; } int CharacterBody3D::get_max_slides() const { @@ -1965,10 +1963,10 @@ void CharacterBody3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_slide_on_ceiling_enabled", "enabled"), &CharacterBody3D::set_slide_on_ceiling_enabled); ClassDB::bind_method(D_METHOD("is_slide_on_ceiling_enabled"), &CharacterBody3D::is_slide_on_ceiling_enabled); - ClassDB::bind_method(D_METHOD("set_moving_platform_floor_layers", "exclude_layer"), &CharacterBody3D::set_moving_platform_floor_layers); - ClassDB::bind_method(D_METHOD("get_moving_platform_floor_layers"), &CharacterBody3D::get_moving_platform_floor_layers); - ClassDB::bind_method(D_METHOD("set_moving_platform_wall_layers", "exclude_layer"), &CharacterBody3D::set_moving_platform_wall_layers); - ClassDB::bind_method(D_METHOD("get_moving_platform_wall_layers"), &CharacterBody3D::get_moving_platform_wall_layers); + ClassDB::bind_method(D_METHOD("set_platform_floor_layers", "exclude_layer"), &CharacterBody3D::set_platform_floor_layers); + ClassDB::bind_method(D_METHOD("get_platform_floor_layers"), &CharacterBody3D::get_platform_floor_layers); + ClassDB::bind_method(D_METHOD("set_platform_wall_layers", "exclude_layer"), &CharacterBody3D::set_platform_wall_layers); + ClassDB::bind_method(D_METHOD("get_platform_wall_layers"), &CharacterBody3D::get_platform_wall_layers); ClassDB::bind_method(D_METHOD("get_max_slides"), &CharacterBody3D::get_max_slides); ClassDB::bind_method(D_METHOD("set_max_slides", "max_slides"), &CharacterBody3D::set_max_slides); @@ -1982,8 +1980,8 @@ void CharacterBody3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_up_direction", "up_direction"), &CharacterBody3D::set_up_direction); ClassDB::bind_method(D_METHOD("set_motion_mode", "mode"), &CharacterBody3D::set_motion_mode); ClassDB::bind_method(D_METHOD("get_motion_mode"), &CharacterBody3D::get_motion_mode); - ClassDB::bind_method(D_METHOD("set_moving_platform_apply_velocity_on_leave", "on_leave_apply_velocity"), &CharacterBody3D::set_moving_platform_apply_velocity_on_leave); - ClassDB::bind_method(D_METHOD("get_moving_platform_apply_velocity_on_leave"), &CharacterBody3D::get_moving_platform_apply_velocity_on_leave); + ClassDB::bind_method(D_METHOD("set_platform_on_leave", "on_leave_apply_velocity"), &CharacterBody3D::set_platform_on_leave); + ClassDB::bind_method(D_METHOD("get_platform_on_leave"), &CharacterBody3D::get_platform_on_leave); ClassDB::bind_method(D_METHOD("is_on_floor"), &CharacterBody3D::is_on_floor); ClassDB::bind_method(D_METHOD("is_on_floor_only"), &CharacterBody3D::is_on_floor_only); @@ -2016,10 +2014,10 @@ void CharacterBody3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_max_angle", PROPERTY_HINT_RANGE, "0,180,0.1,radians"), "set_floor_max_angle", "get_floor_max_angle"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_snap_length", PROPERTY_HINT_RANGE, "0,1,0.01,or_greater,suffix:m"), "set_floor_snap_length", "get_floor_snap_length"); - ADD_GROUP("Moving Platform", "moving_platform"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "moving_platform_apply_velocity_on_leave", PROPERTY_HINT_ENUM, "Always,Upward Only,Never", PROPERTY_USAGE_DEFAULT), "set_moving_platform_apply_velocity_on_leave", "get_moving_platform_apply_velocity_on_leave"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "moving_platform_floor_layers", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_moving_platform_floor_layers", "get_moving_platform_floor_layers"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "moving_platform_wall_layers", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_moving_platform_wall_layers", "get_moving_platform_wall_layers"); + ADD_GROUP("Moving Platform", "platform_"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "platform_on_leave", PROPERTY_HINT_ENUM, "Add Velocity,Add Upward Velocity,Do Nothing", PROPERTY_USAGE_DEFAULT), "set_platform_on_leave", "get_platform_on_leave"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "platform_floor_layers", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_platform_floor_layers", "get_platform_floor_layers"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "platform_wall_layers", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_platform_wall_layers", "get_platform_wall_layers"); ADD_GROUP("Collision", ""); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001,suffix:m"), "set_safe_margin", "get_safe_margin"); @@ -2027,9 +2025,9 @@ void CharacterBody3D::_bind_methods() { BIND_ENUM_CONSTANT(MOTION_MODE_GROUNDED); BIND_ENUM_CONSTANT(MOTION_MODE_FLOATING); - BIND_ENUM_CONSTANT(PLATFORM_VEL_ON_LEAVE_ALWAYS); - BIND_ENUM_CONSTANT(PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY); - BIND_ENUM_CONSTANT(PLATFORM_VEL_ON_LEAVE_NEVER); + BIND_ENUM_CONSTANT(PLATFORM_ON_LEAVE_ADD_VELOCITY); + BIND_ENUM_CONSTANT(PLATFORM_ON_LEAVE_ADD_UPWARD_VELOCITY); + BIND_ENUM_CONSTANT(PLATFORM_ON_LEAVE_DO_NOTHING); } void CharacterBody3D::_validate_property(PropertyInfo &p_property) const { diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h index 200eee0b98..14a1cf7228 100644 --- a/scene/3d/physics_body_3d.h +++ b/scene/3d/physics_body_3d.h @@ -348,10 +348,10 @@ public: MOTION_MODE_GROUNDED, MOTION_MODE_FLOATING, }; - enum MovingPlatformApplyVelocityOnLeave { - PLATFORM_VEL_ON_LEAVE_ALWAYS, - PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY, - PLATFORM_VEL_ON_LEAVE_NEVER, + enum PlatformOnLeave { + PLATFORM_ON_LEAVE_ADD_VELOCITY, + PLATFORM_ON_LEAVE_ADD_UPWARD_VELOCITY, + PLATFORM_ON_LEAVE_DO_NOTHING, }; bool move_and_slide(); @@ -383,7 +383,7 @@ public: private: real_t margin = 0.001; MotionMode motion_mode = MOTION_MODE_GROUNDED; - MovingPlatformApplyVelocityOnLeave moving_platform_apply_velocity_on_leave = PLATFORM_VEL_ON_LEAVE_ALWAYS; + PlatformOnLeave platform_on_leave = PLATFORM_ON_LEAVE_ADD_VELOCITY; union CollisionState { uint32_t state = 0; struct { @@ -411,8 +411,8 @@ private: int platform_layer = 0; RID platform_rid; ObjectID platform_object_id; - uint32_t moving_platform_floor_layers = UINT32_MAX; - uint32_t moving_platform_wall_layers = 0; + uint32_t platform_floor_layers = UINT32_MAX; + uint32_t platform_wall_layers = 0; real_t floor_snap_length = 0.1; real_t floor_max_angle = Math::deg2rad((real_t)45.0); real_t wall_min_slide_angle = Math::deg2rad((real_t)15.0); @@ -457,17 +457,17 @@ private: real_t get_wall_min_slide_angle() const; void set_wall_min_slide_angle(real_t p_radians); - uint32_t get_moving_platform_floor_layers() const; - void set_moving_platform_floor_layers(const uint32_t p_exclude_layer); + uint32_t get_platform_floor_layers() const; + void set_platform_floor_layers(const uint32_t p_exclude_layer); - uint32_t get_moving_platform_wall_layers() const; - void set_moving_platform_wall_layers(const uint32_t p_exclude_layer); + uint32_t get_platform_wall_layers() const; + void set_platform_wall_layers(const uint32_t p_exclude_layer); void set_motion_mode(MotionMode p_mode); MotionMode get_motion_mode() const; - void set_moving_platform_apply_velocity_on_leave(MovingPlatformApplyVelocityOnLeave p_on_leave_velocity); - MovingPlatformApplyVelocityOnLeave get_moving_platform_apply_velocity_on_leave() const; + void set_platform_on_leave(PlatformOnLeave p_on_leave_velocity); + PlatformOnLeave get_platform_on_leave() const; void _move_and_slide_floating(double p_delta); void _move_and_slide_grounded(double p_delta, bool p_was_on_floor); @@ -488,7 +488,7 @@ protected: }; VARIANT_ENUM_CAST(CharacterBody3D::MotionMode); -VARIANT_ENUM_CAST(CharacterBody3D::MovingPlatformApplyVelocityOnLeave); +VARIANT_ENUM_CAST(CharacterBody3D::PlatformOnLeave); class KinematicCollision3D : public RefCounted { GDCLASS(KinematicCollision3D, RefCounted); diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 0cd7188c23..1bc138704e 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -613,42 +613,6 @@ Vector<int> Skeleton3D::get_bone_children(int p_bone) { return bones[p_bone].child_bones; } -void Skeleton3D::set_bone_children(int p_bone, Vector<int> p_children) { - const int bone_size = bones.size(); - ERR_FAIL_INDEX(p_bone, bone_size); - bones.write[p_bone].child_bones = p_children; - - process_order_dirty = true; - rest_dirty = true; - _make_dirty(); -} - -void Skeleton3D::add_bone_child(int p_bone, int p_child) { - const int bone_size = bones.size(); - ERR_FAIL_INDEX(p_bone, bone_size); - bones.write[p_bone].child_bones.push_back(p_child); - - process_order_dirty = true; - rest_dirty = true; - _make_dirty(); -} - -void Skeleton3D::remove_bone_child(int p_bone, int p_child) { - const int bone_size = bones.size(); - ERR_FAIL_INDEX(p_bone, bone_size); - - int child_idx = bones[p_bone].child_bones.find(p_child); - if (child_idx >= 0) { - bones.write[p_bone].child_bones.remove_at(child_idx); - } else { - WARN_PRINT("Cannot remove child bone: Child bone not found."); - } - - process_order_dirty = true; - rest_dirty = true; - _make_dirty(); -} - Vector<int> Skeleton3D::get_parentless_bones() { _update_process_order(); return parentless_bones; @@ -1238,9 +1202,6 @@ void Skeleton3D::_bind_methods() { ClassDB::bind_method(D_METHOD("unparent_bone_and_rest", "bone_idx"), &Skeleton3D::unparent_bone_and_rest); ClassDB::bind_method(D_METHOD("get_bone_children", "bone_idx"), &Skeleton3D::get_bone_children); - ClassDB::bind_method(D_METHOD("set_bone_children", "bone_idx", "bone_children"), &Skeleton3D::set_bone_children); - ClassDB::bind_method(D_METHOD("add_bone_child", "bone_idx", "child_bone_idx"), &Skeleton3D::add_bone_child); - ClassDB::bind_method(D_METHOD("remove_bone_child", "bone_idx", "child_bone_idx"), &Skeleton3D::remove_bone_child); ClassDB::bind_method(D_METHOD("get_parentless_bones"), &Skeleton3D::get_parentless_bones); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 4a3a35383e..2b19ee4d0b 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -3718,12 +3718,17 @@ bool Tree::edit_selected() { } else if (c.mode == TreeItem::CELL_MODE_STRING || c.mode == TreeItem::CELL_MODE_RANGE) { Rect2 popup_rect; - Vector2 ofs(0, (text_editor->get_size().height - rect.size.height) / 2); + Vector2 ofs(0, Math::floor((text_editor->get_size().height - rect.size.height) / 2)); // "floor()" centers vertically. Point2i textedpos = get_screen_position() + rect.position - ofs; cache.text_editor_position = textedpos; popup_rect.position = textedpos; popup_rect.size = rect.size; + + // Account for icon. + popup_rect.position.x += c.get_icon_size().x; + popup_rect.size.x -= c.get_icon_size().x; + text_editor->clear(); text_editor->set_text(c.mode == TreeItem::CELL_MODE_STRING ? c.text : String::num(c.val, Math::range_step_decimals(c.step))); text_editor->select_all(); diff --git a/servers/audio/audio_driver_dummy.cpp b/servers/audio/audio_driver_dummy.cpp index 60eb657923..729f278d4b 100644 --- a/servers/audio/audio_driver_dummy.cpp +++ b/servers/audio/audio_driver_dummy.cpp @@ -36,9 +36,8 @@ AudioDriverDummy *AudioDriverDummy::singleton = nullptr; Error AudioDriverDummy::init() { - active = false; - thread_exited = false; - exit_thread = false; + active.clear(); + exit_thread.clear(); samples_in = nullptr; if (mix_rate == -1) { @@ -60,23 +59,23 @@ void AudioDriverDummy::thread_func(void *p_udata) { uint64_t usdelay = (ad->buffer_frames / float(ad->mix_rate)) * 1000000; - while (!ad->exit_thread) { - if (ad->active) { + while (!ad->exit_thread.is_set()) { + if (ad->active.is_set()) { ad->lock(); + ad->start_counting_ticks(); ad->audio_server_process(ad->buffer_frames, ad->samples_in); + ad->stop_counting_ticks(); ad->unlock(); }; OS::get_singleton()->delay_usec(usdelay); }; - - ad->thread_exited = true; }; void AudioDriverDummy::start() { - active = true; + active.set(); }; int AudioDriverDummy::get_mix_rate() const { @@ -113,7 +112,7 @@ uint32_t AudioDriverDummy::get_channels() const { } void AudioDriverDummy::mix_audio(int p_frames, int32_t *p_buffer) { - ERR_FAIL_COND(!active); // If not active, should not mix. + ERR_FAIL_COND(!active.is_set()); // If not active, should not mix. ERR_FAIL_COND(use_threads == true); // If using threads, this will not work well. uint32_t todo = p_frames; @@ -136,7 +135,7 @@ void AudioDriverDummy::mix_audio(int p_frames, int32_t *p_buffer) { void AudioDriverDummy::finish() { if (use_threads) { - exit_thread = true; + exit_thread.set(); thread.wait_to_finish(); } diff --git a/servers/audio/audio_driver_dummy.h b/servers/audio/audio_driver_dummy.h index 8f47e64d8b..46dd2e1439 100644 --- a/servers/audio/audio_driver_dummy.h +++ b/servers/audio/audio_driver_dummy.h @@ -35,6 +35,7 @@ #include "core/os/mutex.h" #include "core/os/thread.h" +#include "core/templates/safe_refcount.h" class AudioDriverDummy : public AudioDriver { Thread thread; @@ -50,9 +51,8 @@ class AudioDriverDummy : public AudioDriver { int channels; - bool active; - bool thread_exited; - mutable bool exit_thread; + SafeFlag active; + SafeFlag exit_thread; bool use_threads = true; |